#*
  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" )
#
#set ( $package = "${packageModelV4}" )
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
#foreach ( $class in $model.allClasses )
  #set ( $ancestors = $Helper.ancestors( $class ) )
  #set ( $allFields = [] )
  #set ( $inheritedFields = [] )
  #foreach ( $cl in $ancestors )
    #if ( $cl != $class )
      #set ( $dummy = $inheritedFields.addAll( $cl.getFields($version) ) )
    #end
    #set ( $dummy = $allFields.addAll( $cl.getFields($version) ) )
  #end
  #set ( $className = "${class.name}" )
  #if ( $locationTracking && $generateLocationClasses )
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/InputLocation.java
    #parse ( "java/InputLocation.java" )
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/InputLocationTracker.java
    #parse ( "java/InputLocationTracker.java" )
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/InputSource.java
    #parse ( "java/InputSource.java" )
  #end
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/ImmutableCollections.java
#parse ( "java/ImmutableCollections.java" )
  #if ( $class.name != "InputLocation" && $class.name != "InputSource" )
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/${className}.java
    #set ( $types = { } )
    #set ( $imports = $class.getClass().forName("java.util.TreeSet").newInstance() )
    #set ( $dummy = $imports.add( "java.io.Serializable" ) )
    #set ( $dummy = $imports.add( "java.util.Collections" ) )
    #set ( $dummy = $imports.add( "java.util.HashMap" ) )
    #set ( $dummy = $imports.add( "java.util.Map" ) )
    #set ( $dummy = $imports.add( "java.util.Objects" ) )
    #set ( $dummy = $imports.add( "java.util.Optional" ) )
    #set ( $dummy = $imports.add( "java.util.Set" ) )
    #set ( $dummy = $imports.add( "java.util.stream.Collectors" ) )
    #set ( $dummy = $imports.add( "java.util.stream.Stream" ) )
    #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Experimental" ) )
    #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Generated" ) )
    #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Immutable" ) )
    #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.Nonnull" ) )
    #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.NotThreadSafe" ) )
    #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.ThreadSafe" ) )
    #if ( $package == "org.apache.maven.api.model" )
    #set ( $dummy = $imports.add( "org.apache.maven.api.model.ModelObjectProcessor" ) )
    #end
    #foreach ( $field in $allFields )
      #if ( $field.type == "java.util.List" )
        #set ( $dummy = $imports.add( "java.util.ArrayList" ) )
        #set ( $dummy = $imports.add( "java.util.Collection" ) )
        #set ( $dummy = $imports.add( "java.util.List" ) )
        #set ( $dummy = $types.put( $field, "List<" + $field.to + ">" ) )
      #elseif ( $field.type == "java.util.Properties" )
        #set ( $dummy = $imports.add( "java.util.Map" ) )
        #set ( $dummy = $types.put( $field, "Map<String, String>" ) )
      #elseif ( $field.type == "DOM" )
        #set ( $dummy = $imports.add( "org.apache.maven.api.xml.XmlNode" ) )
        #set ( $dummy = $types.put( $field, "XmlNode" ) )
      #else
        #set ( $fieldType = ${types.getOrDefault($field.type,$field.type)} )
        #set ( $idx = $fieldType.lastIndexOf('.') )
        #if ( $idx > 0 )
          #set ( $dummy = $imports.add( $fieldType ) )
          #set ( $dummy = $types.put( $fieldType, $fieldType.substring( $idx + 1 ) ) )
        #end
      #end
    #end
    #set ( $eq = "" )
    #set ( $hc = "" )
    #foreach ( $field in $allFields )
      #if ( $field.identifier )
        #set ( $dummy = $imports.add( "java.util.Objects" ) )
        #set ( $dummy = $identifiers.add( $field ) )
        #if ( $eq == "" )
          #set ( $eq = "Objects.equals( this.${field.name}, that.${field.name} )" )
        #else
          #set ( $eq = "$eq && Objects.equals( this.${field.name}, that.${field.name} )" )
        #end
        #if ( $hc == "" )
          #set ( $hc = "${field.name}" )
        #else
          #set ( $hc = "$hc, this.${field.name}" )
        #end
      #end
    #end
// =================== DO NOT EDIT THIS FILE ====================
//  Generated by Modello Velocity from ${template}
//  template, any modifications will be overwritten.
// ==============================================================
package ${package};

    #foreach ( $imp in $imports )
import $imp;
    #end

/**
    #foreach ( $line in ${class.description.trim().split("\n")} )
 * ${line.trim()}
    #end
 */
#foreach( $ann in ${class.annotations} )
${ann}
#end
@Experimental
@Generated @ThreadSafe @Immutable
public class ${class.name}
    #if ( $class.superClass )
    extends ${class.superClass}
    #end
    #if ( $locationTracking )
    implements Serializable, InputLocationTracker
    #else
    implements Serializable
    #end
{
    #if ( $class == $root )
    final String namespaceUri;
    final String modelEncoding;
    #end
    #foreach ( $field in $class.getFields($version) )
      #set ( $type = ${types.getOrDefault($field,${types.getOrDefault($field.type,$field.type)})} )
    /**
      #foreach ( $line in ${field.description.trim().split("\n")} )
     * ${line.trim()}
      #end
     */
      #foreach( $ann in ${field.annotations} )
    ${ann}
      #end
    final ${type} $field.name;
    #end
    #if ( $locationTracking && ! $class.superClass )
    /** Locations */
    final Map<Object, InputLocation> locations;
    /** Location tracking */
    final InputLocation importedFrom;
    #end

    /**
      * Constructor for this class, to be called from its subclasses and {@link Builder}.
      * @see Builder#build()
      */
    protected ${class.name}(Builder builder) {
    #if ( $class.superClass )
        super(builder);
    #end
    #if ( $class == $root )
        this.namespaceUri = builder.namespaceUri != null ? builder.namespaceUri : (builder.base != null ? builder.base.namespaceUri : null);
        this.modelEncoding = builder.modelEncoding != null ? builder.modelEncoding : (builder.base != null ? builder.base.modelEncoding :  "UTF-8");
    #end
    #foreach ( $field in $class.getFields($version) )
      #if ( $field.type == "java.util.List" || $field.type == "java.util.Properties" || $field.type == "java.util.Map" )
        this.${field.name} = ImmutableCollections.copy(builder.${field.name} != null ? builder.${field.name} : (builder.base != null ? builder.base.${field.name} : null));
      #else
        #if ( $field.type == "boolean" || $field.type == "int" )
        this.${field.name} = builder.${field.name} != null ? builder.${field.name} : (builder.base != null ? builder.base.${field.name} : ${field.defaultValue});
        #else
        this.${field.name} = builder.${field.name} != null ? builder.${field.name} : (builder.base != null ? builder.base.${field.name} : null);
        #end
      #end
    #end
    #if ( $locationTracking && ! $class.superClass )
        this.locations = builder.computeLocations();
        this.importedFrom = builder.importedFrom;
    #end
    }

    #if ( ! $eq.empty )
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || !(o instanceof ${class.name})) {
            return false;
        }
        ${class.name} that = (${class.name}) o;
        return ${eq};
    }

    @Override
    public int hashCode() {
        return Objects.hash(${hc});
    }

    #end
    #if ( $class == $root )
    public String getNamespaceUri() {
        return namespaceUri;
    }

    public String getModelEncoding() {
        return modelEncoding;
    }

    #end
    #foreach ( $field in $class.getFields($version) )
      #set ( $cap = $Helper.capitalise( $field.name ) )
      #set ( $type = ${types.getOrDefault($field,${types.getOrDefault($field.type,$field.type)})} )
      #if ( $type == "boolean" || $type == "Boolean" )
        #set ( $pfx = "is" )
      #else
        #set ( $pfx = "get" )
      #end
    /**
      #set ( $desc = ${field.description.trim()} )
      #foreach ( $line in ${desc.split("\n")} )
     * ${line.trim()}
      #end
     *
     * @return a {@code ${type}}
     */
      #foreach( $ann in ${field.annotations} )
    ${ann}
      #end
      #if ( $field.type == "java.util.List" || $field.type == "java.util.Properties" )
    @Nonnull
      #end
    public ${type} ${pfx}${cap}() {
        return this.${field.name};
    }

    #end
    #if ( $locationTracking && !$class.superClass )
    /**
     * Gets the location of the specified field in the input source.
     *
     * @param key the key of the field, must not be {@code null}
     * @return the location of the field in the input source or {@code null} if unknown
     * @throws NullPointerException if {@code key} is {@code null}
     */
    public InputLocation getLocation(Object key) {
        Objects.requireNonNull(key, "key");
        return locations.get(key);
    }

    /**
     * Gets the keys of the locations of the input source.
     */
    public Set<Object> getLocationKeys() {
        return locations.keySet();
    }

    protected Stream<Object> getLocationKeyStream() {
        return locations.keySet().stream();
    }

    /**
     * Gets the input location that caused this model to be read.
     */
    public InputLocation getImportedFrom() {
        return importedFrom;
    }

    #end
    /**
     * Creates a new builder with this object as the basis.
     *
     * @return a {@code Builder}
     */
    @Nonnull
    public Builder with() {
        return newBuilder(this);
    }
    #foreach ( $field in $allFields )
      #set ( $cap = $Helper.capitalise( $field.name ) )
      #set ( $type = ${types.getOrDefault($field,${types.getOrDefault($field.type,$field.type)})} )
      #if ( $type.startsWith("List<") )
        #set ( $type = ${type.replace('List<','Collection<')} )
      #end
    /**
     * Creates a new {@code ${class.name}} instance using the specified ${field.name}.
     *
     * @param ${field.name} the new {@code $type} to use
     * @return a {@code ${class.name}} with the specified ${field.name}
     */
      #foreach( $ann in ${field.annotations} )
    ${ann}
      #end
    @Nonnull
    public ${class.name} with${cap}($type $field.name) {
        return newBuilder(this, true).${field.name}($field.name).build();
    }
    #end

    /**
     * Creates a new {@code ${class.name}} instance.
     * Equivalent to {@code newInstance(true)}.
     * @see #newInstance(boolean)
     *
     * @return a new {@code ${class.name}}
     */
    @Nonnull
    public static ${class.name} newInstance() {
        return newInstance(true);
    }

    /**
     * Creates a new {@code ${class.name}} instance using default values or not.
     * Equivalent to {@code newBuilder(withDefaults).build()}.
     *
     * @param withDefaults the boolean indicating whether default values should be used
     * @return a new {@code ${class.name}}
     */
    @Nonnull
    public static ${class.name} newInstance(boolean withDefaults) {
        return newBuilder(withDefaults).build();
    }

    /**
     * Creates a new {@code ${class.name}} builder instance.
     * Equivalent to {@code newBuilder(true)}.
     * @see #newBuilder(boolean)
     *
     * @return a new {@code Builder}
     */
    @Nonnull
    public static Builder newBuilder() {
        return newBuilder(true);
    }

    /**
     * Creates a new {@code ${class.name}} builder instance using default values or not.
     *
     * @param withDefaults the boolean indicating whether default values should be used
     * @return a new {@code Builder}
     */
    @Nonnull
    public static Builder newBuilder(boolean withDefaults) {
        return new Builder(withDefaults);
    }

    /**
     * Creates a new {@code ${class.name}} builder instance using the specified object as a basis.
     * Equivalent to {@code newBuilder(from, false)}.
     *
     * @param from the {@code ${class.name}} instance to use as a basis
     * @return a new {@code Builder}
     */
    @Nonnull
    public static Builder newBuilder(${class.name} from) {
        return newBuilder(from, false);
    }

    /**
     * Creates a new {@code ${class.name}} builder instance using the specified object as a basis.
     *
     * @param from the {@code ${class.name}} instance to use as a basis
     * @param forceCopy the boolean indicating if a copy should be forced
     * @return a new {@code Builder}
     */
    @Nonnull
    public static Builder newBuilder(${class.name} from, boolean forceCopy) {
        return new Builder(from, forceCopy);
    }

    /**
     * Builder class used to create ${class.name} instances.
     * @see #with()
     * @see #newBuilder()
     */
    @NotThreadSafe
    public static class Builder
    #if ( $class.superClass )
        extends ${class.superClass}.Builder
    #end
    {
        ${class.name} base;
    #if ( $class == $root )
        String namespaceUri;
        String modelEncoding;
    #end
    #foreach ( $field in $class.getFields($version) )
      #set ( $type = ${types.getOrDefault($field,${types.getOrDefault($field.type,$field.type)})} )
      #if ( $type.startsWith("List<") )
        #set ( $type = ${type.replace('List<','Collection<')} )
      #end
      #if ( $type == 'boolean' )
        Boolean ${field.name};
      #elseif ( $type == 'int' )
        Integer ${field.name};
      #else
        ${type} ${field.name};
    #end
    #end
    #if ( ! $class.superClass && $locationTracking )
        Map<Object, InputLocation> locations;
        InputLocation importedFrom;
    #end

        protected Builder(boolean withDefaults) {
    #if ( $class.superClass )
            super(withDefaults);
    #end
            if (withDefaults) {
    #foreach ( $field in $class.getFields($version) )
      #if ( $field.defaultValue )
        #set ( $type = ${types.getOrDefault($field,${types.getOrDefault($field.type,$field.type)})} )
        #if ( $field.type == "String" )
                this.${field.name} = "${field.defaultValue}";
        #elseif ( $field.type != "java.util.List" && $field.type != "java.util.Properties" )
                this.${field.name} = ${field.defaultValue};
        #end
      #end
    #end
            }
        }

        protected Builder(${class.name} base, boolean forceCopy) {
    #if ( $class.superClass )
            super(base, forceCopy);
    #end
    #if ( $class == $root )
            this.namespaceUri = base.namespaceUri;
            this.modelEncoding = base.modelEncoding;
    #end
            if (forceCopy) {
    #foreach ( $field in $class.getFields($version) )
                this.${field.name} = base.${field.name};
    #end
    #if ( $locationTracking )
                this.locations = base.locations;
                this.importedFrom = base.importedFrom;
    #end
            } else {
                this.base = base;
            }
        }

    #if ( $class == $root )
        @Nonnull
        public Builder namespaceUri(String namespaceUri) {
            this.namespaceUri = namespaceUri;
            return this;
        }

        @Nonnull
        public Builder modelEncoding(String modelEncoding) {
            this.modelEncoding = modelEncoding;
            return this;
        }

    #end
    #foreach ( $field in $allFields )
      #set ( $type = ${types.getOrDefault($field,${types.getOrDefault($field.type,$field.type)})} )
      #if ( $type.startsWith("List<") )
        #set ( $type = ${type.replace('List<','Collection<')} )
      #end
      #foreach( $ann in ${field.annotations} )
        ${ann}
      #end
        @Nonnull
        public Builder ${field.name}(${type} ${field.name}) {
            this.${field.name} = ${field.name};
            return this;
        }

    #end

    #if ( $locationTracking )
        @Nonnull
        public Builder location(Object key, InputLocation location) {
            if (location != null) {
                if (!(this.locations instanceof HashMap)) {
                    this.locations = this.locations != null ? new HashMap<>(this.locations) : new HashMap<>();
                }
                this.locations.put(key, location);
            }
            return this;
        }

        @Nonnull
        public Builder importedFrom(InputLocation importedFrom) {
            this.importedFrom = importedFrom;
            return this;
        }

    #end
        @Nonnull
        public ${class.name} build() {
            // this method should not contain any logic other than creating (or reusing) an object in order to ease subclassing
            if (base != null
    #foreach ( $field in $allFields )
                    && (${field.name} == null || ${field.name} == base.${field.name})
    #end
            ) {
                return base;
            }
            ${class.name} newInstance = new ${class.name}(this);
    #if ( $package == "org.apache.maven.api.model" )
            return ModelObjectProcessor.processObject(newInstance);
    #else
            return newInstance;
    #end
        }

    #if ( $locationTracking && ! $class.superClass )
        Map<Object, InputLocation> computeLocations() {
            Map<Object, InputLocation> newlocs = locations != null ? locations : Map.of();
            Map<Object, InputLocation> oldlocs = base != null ? base.locations : Map.of();
            if (newlocs.isEmpty()) {
                return Map.copyOf(oldlocs);
            }
            if (oldlocs.isEmpty()) {
                return Map.copyOf(newlocs);
            }
            return Stream.concat(newlocs.entrySet().stream(), oldlocs.entrySet().stream())
                    // Keep value from newlocs in case of duplicates
                    .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1));
        }
    #end
    }

    #foreach ( $cs in $class.getCodeSegments($version) )
$cs.code
    #end
}
  #end
#end
