#*
  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 = "${packageToolV4}" )
#set ( $className = "${model.name}ModelVersion" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
#
#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.ObjectStreamException;
import java.nio.file.Path;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.maven.api.annotations.Generated;
import org.apache.maven.api.xml.XmlNode;
#foreach ( $class in $model.allClasses )
import ${packageModelV4}.${class.Name};
#end

@Generated
public class ${className} {

    public String getModelVersion(${root.name} model) {
        Objects.requireNonNull(model, "model cannot be null");

#set ( $String = $model.getClass().forName("java.lang.String") )
#set ( $Comparator = $model.getClass().forName("java.util.Comparator") )
#set ( $LinkedHashSet = $model.getClass().forName("java.util.LinkedHashSet") )
#set ( $HashMap = $model.getClass().forName("java.util.HashMap") )
#set ( $TreeSet = $model.getClass().forName("java.util.TreeSet") )
#set ( $Version = $model.getClass().forName("org.codehaus.modello.model.Version") )
#set ( $versions = $TreeSet.getConstructor( $Comparator ).newInstance( $Comparator.reverseOrder() ) )
#foreach ( $class in $model.allClasses )
    #set ( $dummy = $versions.add( $class.versionRange.fromVersion ) )
    #foreach ( $field in $class.allFields )
        #if ( ! $Helper.xmlFieldMetadata( $field ).transient )
            #set ( $dummy = $versions.add( $field.versionRange.fromVersion ) )
        #end
    #end
#end
#if ( $minimalVersion )
    #set ( $minimal = $Version.getConstructor( $String ).newInstance( $minimalVersion ) )
    #set ( $versions = $versions.headSet( $minimal, false ) )
#else
    #set ( $dummy = $versions.remove( $Version.getConstructor( $String ).newInstance( "0.0.0" ) ) )
#end
#set ( $dummy = $versions.remove( $Version.getConstructor( $String ).newInstance( "32767.32767.32767" ) ) )
#foreach ( $version in $versions )
    #set ( $v = $version.toString().replace('.', '_') )
        // ${version}
        if (is_${v}(model)) {
            return "${version}";
        }
#end
#if ( $minimalVersion )
        return "$minimalVersion";
#else
        return null;
#end
    }

#foreach ( $version in $versions )
    #set ( $v = $version.toString().replace('.', '_') )
    #set ( $classesToCheck = $TreeSet.newInstance() )
    #set ( $classToFields = $HashMap.newInstance() )
    #foreach($unused in [1..10])
        #foreach ( $class in $model.allClasses )
            #foreach ( $field in $class.allFields )
                #if ( ! $Helper.xmlFieldMetadata( $field ).transient )
                    #set ( $newInVersion = $field.versionRange.fromVersion.equals($version) )
                    #set ( $isAsso = false )
                    #if ( $field.toClass )
                        #set ( $ancestors = $Helper.ancestors( $field.toClass ) )
                        #foreach ( $cl in $ancestors )
                            #if ( $classToFields.containsKey( $cl ) )
                                #set ( $isAsso = true )
                            #end
                        #end
                    #end
                    #if ( $newInVersion || $isAsso )
                        #set ( $fields = $classToFields.get( $class ) )
                        #if ( ! $fields )
                            #set ( $fields = $LinkedHashSet.newInstance() )
                            #set ( $dummy = $classToFields.put( $class, $fields ) )
                        #end
                        #set( $dummy = $fields.add($field) )
                        #if ( $dummy )
                        #end
                    #end
                #end
            #end
            #if ( $class.superClass )
                #if ( $classToFields.containsKey( $model.getClass( $class.superClass, $class.versionRange ) ) )
                    #set ( $fields = $classToFields.get( $class ) )
                    #if ( ! $fields )
                        #set ( $fields = $LinkedHashSet.newInstance() )
                        #set ( $dummy = $classToFields.put( $class, $fields ) )
                    #end
                #end
            #end
        #end
    #end
    #foreach ( $class in $classToFields.keySet() )
        #set ( $var = $Helper.uncapitalise( $class.name ) )
    private boolean is_${v}(${class.name} ${var}) {
        return ${var} != null && (
        #set ( $pfx = "  " )
        #if ( $class.superClass )
            #if ( $classToFields.containsKey( $model.getClass( $class.superClass, $class.versionRange ) ) )
            $pfx is_${v}((${class.superClass}) ${var})
                #set ( $pfx = "||" )
            #end
        #end
        #foreach ( $field in $classToFields.get( $class ) )
            #if ( $field.isManyMultiplicity() )
                #if ( $classToFields.containsKey( $field.toClass ) )
            $pfx ${var}.get${Helper.capitalise($field.name)}().stream().anyMatch(this::is_${v}) // ${class.name} : ${field.name}
                #else
            $pfx !${var}.get${Helper.capitalise($field.name)}().isEmpty() // ${class.name} : ${field.name}
                #end
            #elseif ( $field.isOneMultiplicity() )
            $pfx is_${v}(${var}.get${Helper.capitalise($field.name)}()) // ${class.name} : ${field.name}
            #elseif ( $field.type == "boolean" || $field.type == "Boolean" )
            $pfx has(${var}.is${Helper.capitalise($field.name)}()) // ${class.name} : ${field.name}
            #else
            $pfx has(${var}.get${Helper.capitalise($field.name)}()) // ${class.name} : ${field.name}
            #end
            #set ( $pfx = "||" )
        #end
        );
    }
    #end

#end
    private boolean has(String str) {
        return str != null;
    }

    private boolean has(Path path) {
        return path != null;
    }

    private boolean has(boolean bool) {
        return bool;
    }

    private boolean has(int val) {
        return val != 0;
    }

    private boolean has(List<?> list) {
        return !list.isEmpty();
    }

    private boolean has(XmlNode node) {
        return node != null;
    }

}
