#*
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.
*#
#parse ( "common.vm" )
#
#if( ${packageToolV4Xpp3} )
  #set ( $package = "${packageToolV4Xpp3}" )
#else
  #set ( $package = "${packageToolV4}" )
#end
#set ( $className = "${model.name}Xpp3Writer" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
#set ( $rootXml = $Helper.xmlClassMetadata( $root ) )
#set ( $rootTag = $rootXml.tagName )
#set ( $rootUcapName = $Helper.capitalise( $root.name ) )
#set ( $rootLcapName = $Helper.uncapitalise( $root.name ) )
#
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/${className}.java
// =================== DO NOT EDIT THIS FILE ====================
//  Generated by Modello Velocity from ${template}
//  template, any modifications will be overwritten.
// ==============================================================
package ${package};

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import org.apache.maven.api.annotations.Generated;
import org.apache.maven.api.xml.XmlNode;
#foreach ( $class in $model.allClasses )
import ${packageModelV4}.${class.name};
#end
import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
import org.codehaus.plexus.util.xml.pull.MXParser;
import org.codehaus.plexus.util.xml.pull.MXSerializer;
import org.codehaus.plexus.util.xml.pull.XmlPullParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.codehaus.plexus.util.xml.pull.XmlSerializer;

@Deprecated
@Generated
public class ${className} {

      //--------------------------/
     //- Class/Member Variables -/
    //--------------------------/

    /**
     * Field NAMESPACE.
     */
    private static final String NAMESPACE = null;

    /**
     * Field fileComment.
     */
    private String fileComment = null;


      //-----------/
     //- Methods -/
    //-----------/

    /**
     * Method setFileComment.
     *
     * @param fileComment a fileComment object.
     */
    public void setFileComment(String fileComment) {
        this.fileComment = fileComment;
    } //-- void setFileComment(String)

    /**
     * Method write.
     *
     * @param writer a writer object
     * @param ${rootLcapName} a ${root.name} object
     * @throws java.io.IOException java.io.IOException if any
     */
    public void write(Writer writer, ${root.name} ${rootLcapName}) throws java.io.IOException {
        XmlSerializer serializer = new MXSerializer();
        serializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-indentation", "  ");
        serializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-line-separator", "\n");
        serializer.setOutput(writer);
        serializer.startDocument(${rootLcapName}.getModelEncoding(), null);
        write${root.name}("$rootTag", ${rootLcapName}, serializer);
        serializer.endDocument();
    } //-- void write(Writer, ${root.name})

    /**
     * Method write.
     *
     * @param stream a stream object
     * @param ${rootLcapName} a ${root.name} object
     * @throws java.io.IOException java.io.IOException if any
     */
    public void write(OutputStream stream, ${root.name} ${rootLcapName}) throws java.io.IOException {
        XmlSerializer serializer = new MXSerializer();
        serializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-indentation", "  ");
        serializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-line-separator", "\n");
        serializer.setOutput(stream, ${rootLcapName}.getModelEncoding());
        serializer.startDocument(${rootLcapName}.getModelEncoding(), null);
        write${root.name}("$rootTag", ${rootLcapName}, serializer);
        serializer.endDocument();
    } //-- void write(OutputStream, ${root.name})

#foreach ( $class in $model.allClasses )
 #if ( $class.name != "InputSource" && $class.name != "InputLocation" )
  #set ( $classUcapName = $Helper.capitalise( $class.name ) )
  #set ( $classLcapName = $Helper.uncapitalise( $class.name ) )
  #set ( $allFields = $Helper.xmlFields( $class ) )
    private void write${classUcapName}(String tagName, ${classUcapName} ${classLcapName}, XmlSerializer serializer) throws IOException {
        if (${classLcapName} != null) {
  #if ( $class == $root )
            if (this.fileComment != null) {
                serializer.comment(this.fileComment);
            }
            serializer.setPrefix("", "http://maven.apache.org/POM/4.0.0");
            serializer.setPrefix("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            serializer.startTag(NAMESPACE, tagName);
            serializer.attribute("", "xsi:schemaLocation", "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd");
  #else
            serializer.startTag(NAMESPACE, tagName);
  #end
  #foreach ( $field in $allFields )
    #if ( $Helper.xmlFieldMetadata( $field ).attribute )
      #set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
      #if ( ! $fieldTagName )
        #set ( $fieldTagName = $field.name )
      #end
      #set ( $fieldCapName = $Helper.capitalise( $field.name ) )
      #if ( $field.type == "String" )
            writeAttr("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer);
      #elseif ( $field.type == "boolean" )
        #set ( $def = ${field.defaultValue} )
        #if ( ${def} == "true" )
            writeAttr("$fieldTagName", ${classLcapName}.is${fieldCapName}() ? null : "false", serializer);
        #else
            writeAttr("$fieldTagName", ${classLcapName}.is${fieldCapName}() ? "true" : null, serializer);
        #end
      #elseif ( $field.type == "int" || $field.type == "Integer" )
            writeAttr("$fieldTagName", Integer.toString(${classLcapName}.get${fieldCapName}()), serializer);
      #else
            // TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
      #end
    #end
  #end
  #foreach ( $field in $allFields )
    #if ( ! $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).transient )
      #set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
      #if ( ! $fieldTagName )
        #set ( $fieldTagName = $field.name )
      #end
      #set ( $fieldCapName = $Helper.capitalise( $field.name ) )
      #set ( $def = ${field.defaultValue} )
      #if ( $field.type == "String" )
        #if ( ! $def )
            writeTag("$fieldTagName", null, ${classLcapName}.get${fieldCapName}(), serializer);
        #else
            writeTag("$fieldTagName", "${def}", ${classLcapName}.get${fieldCapName}(), serializer);
        #end
      #elseif ( $field.type == "boolean" || $field.type == "Boolean" )
        #if ( ${def} == "true" )
            writeTag("$fieldTagName", "${def}", ${classLcapName}.is${fieldCapName}() ? null : "false", serializer);
        #else
            writeTag("$fieldTagName", "${def}", ${classLcapName}.is${fieldCapName}() ? "true" : null, serializer);
        #end
      #elseif ( $field.type == "int" )
            writeTag("$fieldTagName", "${def}", Integer.toString(${classLcapName}.get${fieldCapName}()), serializer);
      #elseif ( $field.type == "DOM" )
            writeDom(${classLcapName}.get${fieldCapName}(), serializer);
      #elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
        #set( $singularField = ${Helper.singular($fieldTagName)} )
            writeList("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer, t -> writeTag("$singularField", "${def}", t, serializer));
      #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
            writeProperties("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer);
      #elseif ( $field.to && $field.multiplicity == "1" )
            write${field.to}("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer);
      #elseif ( $field.to && $field.multiplicity == "*" )
        #set( $singularField = ${Helper.singular($fieldTagName)} )
            writeList("$fieldTagName", $Helper.isFlatItems($field), ${classLcapName}.get${fieldCapName}(), serializer, t -> write${field.to}("$singularField", t, serializer));
      #else
            // TODO: name=${field.name} type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
      #end
    #end
  #end
            serializer.endTag(NAMESPACE, tagName);
        }
    }

 #end
#end
    @FunctionalInterface
    private interface ElementWriter<T> {
        public void write(T t) throws IOException;
    }

    private <T> void writeList(String tagName, List<T> list, XmlSerializer serializer, ElementWriter<T> writer) throws IOException {
        writeList(tagName, false, list, serializer, writer);
    }

    private <T> void writeList(String tagName, boolean flat, List<T> list, XmlSerializer serializer, ElementWriter<T> writer) throws IOException {
        if (list != null && !list.isEmpty()) {
            if (!flat) {
                serializer.startTag(NAMESPACE, tagName);
            }
            for (T t : list) {
                writer.write(t);
            }
            if (!flat) {
                serializer.endTag(NAMESPACE, tagName);
            }
        }
    }

    private <T> void writeProperties(String tagName, Map<String, String> props, XmlSerializer serializer) throws IOException {
        if (props != null && !props.isEmpty()) {
            serializer.startTag(NAMESPACE, tagName);
            for (Map.Entry<String, String> entry : props.entrySet()) {
                writeTag(entry.getKey(), null, entry.getValue(), serializer);
            }
            serializer.endTag(NAMESPACE, tagName);
        }
    }

    private void writeDom(XmlNode dom, XmlSerializer serializer) throws IOException {
        if (dom != null) {
            serializer.startTag(NAMESPACE, dom.getName());
            writeXmlNodeAttributes(serializer, dom.getAttributes(), dom.namespaces());
            for (XmlNode child : dom.getChildren()) {
                writeDom(child, serializer);
            }
            String value = dom.getValue();
            if (value != null) {
                serializer.text(value);
            }
            serializer.endTag(NAMESPACE, dom.getName());
        }
    }

    /**
     * Writes XmlNode attributes, properly handling namespace declarations
     * ({@code xmlns:prefix}) and prefixed attributes ({@code prefix:localName}).
     * The namespace context is used to resolve prefixes when the {@code xmlns:}
     * declaration is not present in the attribute map.
     */
    private static void writeXmlNodeAttributes(XmlSerializer serializer, Map<String, String> attributes, Map<String, String> namespaces) throws IOException {
        // Collect which namespace prefixes need to be declared on this element
        Set<String> declaredPrefixes = new HashSet<>();
        for (Map.Entry<String, String> attribute : attributes.entrySet()) {
            String key = attribute.getKey();
            if ("xmlns".equals(key)) {
                serializer.setPrefix("", attribute.getValue());
            } else if (key.startsWith("xmlns:")) {
                String prefix = key.substring(6);
                serializer.setPrefix(prefix, attribute.getValue());
                declaredPrefixes.add(prefix);
            }
        }
        // Write prefixed attributes, declaring their namespace if needed
        for (Map.Entry<String, String> attribute : attributes.entrySet()) {
            String key = attribute.getKey();
            String value = attribute.getValue();
            if ("xmlns".equals(key) || key.startsWith("xmlns:")) {
                continue; // already handled above
            } else if (key.startsWith("xml:")) {
                serializer.attribute("http://www.w3.org/XML/1998/namespace", key.substring(4), value);
            } else if (key.contains(":")) {
                int colon = key.indexOf(':');
                String prefix = key.substring(0, colon);
                String localName = key.substring(colon + 1);
                String nsUri = attributes.get("xmlns:" + prefix);
                if (nsUri == null) {
                    nsUri = namespaces.get(prefix);
                }
                if (nsUri != null) {
                    if (declaredPrefixes.add(prefix)) {
                        serializer.setPrefix(prefix, nsUri);
                    }
                    serializer.attribute(nsUri, localName, value);
                } else {
                    // No namespace declaration for this prefix; write as unprefixed
                    serializer.attribute(NAMESPACE, localName, value);
                }
            } else {
                serializer.attribute(NAMESPACE, key, value);
            }
        }
    }

    private void writeTag(String tagName, String defaultValue, String value, XmlSerializer serializer) throws IOException {
        if (value != null && !Objects.equals(defaultValue, value)) {
            serializer.startTag(NAMESPACE, tagName).text(value).endTag(NAMESPACE, tagName);
        }
    }

    private void writeAttr(String attrName, String value, XmlSerializer serializer) throws IOException {
        if (value != null) {
            serializer.attribute(NAMESPACE, attrName, value);
        }
    }

}
