/*
 * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.tools.xjc.reader.xmlschema;
import static com.sun.tools.xjc.reader.xmlschema.BGMBuilder.getName;

import java.util.Set;

import javax.xml.namespace.QName;

import com.sun.codemodel.JJavaName;
import com.sun.codemodel.JPackage;
import com.sun.istack.NotNull;
import com.sun.istack.Nullable;
import com.sun.tools.xjc.ErrorReceiver;
import com.sun.tools.xjc.model.CClassInfo;
import com.sun.tools.xjc.model.CClassInfoParent;
import com.sun.tools.xjc.model.CClassRef;
import com.sun.tools.xjc.model.CCustomizations;
import com.sun.tools.xjc.model.CElement;
import com.sun.tools.xjc.model.CElementInfo;
import com.sun.tools.xjc.model.Model;
import com.sun.tools.xjc.reader.Ring;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIClass;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIGlobalBinding;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BISchemaBinding;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIXSubstitutable;
import com.sun.tools.xjc.reader.xmlschema.ct.ComplexTypeFieldBuilder;
import com.sun.tools.xjc.reader.xmlschema.ct.ComplexTypeBindingMode;
import com.sun.xml.xsom.XSAnnotation;
import com.sun.xml.xsom.XSAttGroupDecl;
import com.sun.xml.xsom.XSAttributeDecl;
import com.sun.xml.xsom.XSAttributeUse;
import com.sun.xml.xsom.XSComplexType;
import com.sun.xml.xsom.XSComponent;
import com.sun.xml.xsom.XSContentType;
import com.sun.xml.xsom.XSDeclaration;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSFacet;
import com.sun.xml.xsom.XSIdentityConstraint;
import com.sun.xml.xsom.XSModelGroup;
import com.sun.xml.xsom.XSModelGroupDecl;
import com.sun.xml.xsom.XSNotation;
import com.sun.xml.xsom.XSParticle;
import com.sun.xml.xsom.XSSchema;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.XSType;
import com.sun.xml.xsom.XSWildcard;
import com.sun.xml.xsom.XSXPath;

import org.xml.sax.Locator;

/**
 * Default classBinder implementation. Honors {@code <jaxb:class>} customizations
 * and default bindings.
 */
final class DefaultClassBinder implements ClassBinder
{
    private final SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
    private final Model model = Ring.get(Model.class);

    protected final BGMBuilder builder = Ring.get(BGMBuilder.class);
    protected final ClassSelector selector = Ring.get(ClassSelector.class);

    protected final XSSchemaSet schemas = Ring.get(XSSchemaSet.class);

    @Override
    public CElement attGroupDecl(XSAttGroupDecl decl) {
        return allow(decl,decl.getName());
    }

    @Override
    public CElement attributeDecl(XSAttributeDecl decl) {
        return allow(decl,decl.getName());
    }

    @Override
    public CElement modelGroup(XSModelGroup mgroup) {
        return never();
    }

    @Override
    public CElement modelGroupDecl(XSModelGroupDecl decl) {
        return never();
    }


    @Override
    public CElement complexType(XSComplexType type) {
        CElement ci = allow(type,type.getName());
        if(ci!=null)    return ci;

        // no customization is given -- do as the default binding.

        BindInfo bi = builder.getBindInfo(type);

        if(type.isGlobal()) {
            QName tagName = null;
            String className = deriveName(type);
            Locator loc = type.getLocator();

            if(getGlobalBinding().isSimpleMode()) {
                // in the simple mode, we may optimize it away
                XSElementDecl referer = getSoleElementReferer(type);
                if(referer!=null && isCollapsable(referer)) {
                    // if a global element contains
                    // a collpsable complex type, we bind this element to a named one
                    // and collapses element and complex type.
                    tagName = getName(referer);
                    className = deriveName(referer);
                    loc = referer.getLocator();
                }
            }

            // by default, global ones get their own classes.

            JPackage pkg = selector.getPackage(type.getTargetNamespace());

            return new CClassInfo(model,pkg,className, loc,getTypeName(type),tagName,type,bi.toCustomizationList());
        } else {
            XSElementDecl element = type.getScope();

            if( element.isGlobal() && isCollapsable(element)) {
                if(builder.getBindInfo(element).get(BIClass.class)!=null)
                    // the parent element was bound to a class. Don't bind this again to
                    // cause unnecessary wrapping
                    return null;

                // generate one class from element and complex type together.
                // this needs to be done before selector.isBound to avoid infinite recursion.

                // but avoid doing so when the element is mapped to a class,
                // which creates unnecessary classes
                return new CClassInfo( model, selector.getClassScope(),
                    deriveName(element), element.getLocator(), null,
                    getName(element), element, bi.toCustomizationList() );
            }


            CElement parentType = selector.isBound(element,type);

            String className;
            CClassInfoParent scope;


            if( parentType!=null
             && parentType instanceof CElementInfo
             && ((CElementInfo)parentType).hasClass() ) {
                // special case where we put a nested 'Type' element
                scope = (CElementInfo)parentType;
                className = "Type";
            } else {
                // since the parent element isn't bound to a type, merge the customizations associated to it, too.
//                custs = CCustomizations.merge( custs, builder.getBindInfo(type.getScope()).toCustomizationList());
                className = builder.getNameConverter().toClassName(element.getName());

                BISchemaBinding sb = builder.getBindInfo(
                    type.getOwnerSchema() ).get(BISchemaBinding.class);
                if(sb!=null)    className = sb.mangleAnonymousTypeClassName(className);
                scope = selector.getClassScope();
            }

            return new CClassInfo(model, scope, className, type.getLocator(), null, null, type, bi.toCustomizationList() );
        }
    }

    private QName getTypeName(XSComplexType type) {
        if(type.getRedefinedBy()!=null)
            return null;
        else
            return getName(type);
    }

    /**
     * Returns true if the complex type of the given element can be "optimized away"
     * and unified with its parent element decl to form a single class.
     */
    private boolean isCollapsable(XSElementDecl decl) {
        XSType type = decl.getType();

        if(!type.isComplexType())
            return false;   // not a complex type

        if(decl.getSubstitutables().size()>1 || decl.getSubstAffiliation()!=null)
            // because element substitution calls for a proper JAXBElement hierarchy
            return false;

        if(decl.isNillable())
            // because nillable needs JAXBElement to represent correctly
            return false;

        BIXSubstitutable bixSubstitutable = builder.getBindInfo(decl).get(BIXSubstitutable.class);
        if(bixSubstitutable !=null) {
            // see https://jaxb.dev.java.net/issues/show_bug.cgi?id=289
            // this customization forces non-collapsing behavior.
            bixSubstitutable.markAsAcknowledged();
            return false;
        }

        if( getGlobalBinding().isSimpleMode() && decl.isGlobal()) {
            // in the simple mode, we do more aggressive optimization, and get rid of
            // a complex type class if it's only used once from a global element
            XSElementDecl referer = getSoleElementReferer(decl.getType());
            if(referer!=null) {
                assert referer==decl;  // I must be the sole referer
                return true;
            }
        }

        if(!type.isLocal() || !type.isComplexType())
            return false;

        return true;
    }

    /**
     * If only one global {@link XSElementDecl} is refering to {@link XSType},
     * return that element, otherwise null.
     */
    private @Nullable XSElementDecl getSoleElementReferer(@NotNull XSType t) {
        Set<XSComponent> referer = builder.getReferer(t);

        XSElementDecl sole = null;
        for (XSComponent r : referer) {
            if(r instanceof XSElementDecl) {
                XSElementDecl x = (XSElementDecl) r;
                if(!x.isGlobal())
                    // local element references can be ignored, as their names are either given
                    // by the property, or by the JAXBElement (for things like mixed contents)
                    continue;
                if(sole==null)  sole=x;
                else            return null;    // more than one
            } else {
                // if another type refers to this type, that means
                // this type has a sub-type, so type substitution is possible now.
                return null;
            }
        }

        return sole;
    }

    @Override
    public CElement elementDecl(XSElementDecl decl) {
        CElement r = allow(decl,decl.getName());

        if(r==null) {
            QName tagName = getName(decl);
            CCustomizations custs = builder.getBindInfo(decl).toCustomizationList();

            if(decl.isGlobal()) {
                if(isCollapsable(decl)) {
                    // we want the returned type to be built as a complex type,
                    // so the binding cannot be delayed.
                    return selector.bindToType(decl.getType().asComplexType(),decl,true);
                } else {
                    String className = null;
                    if(getGlobalBinding().isGenerateElementClass())
                        className = deriveName(decl);

                    // otherwise map global elements to JAXBElement
                    CElementInfo cei = new CElementInfo(
                        model, tagName, selector.getClassScope(), className, custs, decl.getLocator());
                    selector.boundElements.put(decl,cei);

                    stb.refererStack.push(decl);    // referer is element
                    cei.initContentType( selector.bindToType(decl.getType(),decl), decl, decl.getDefaultValue() );
                    stb.refererStack.pop();
                    r = cei;
                }
            }
        }

        // have the substitution member derive from the substitution head
        XSElementDecl top = decl.getSubstAffiliation();
        if(top!=null) {
            CElement topci = selector.bindToType(top,decl);

            if(r instanceof CClassInfo && topci instanceof CClassInfo)
                ((CClassInfo)r).setBaseClass((CClassInfo)topci);
            if (r instanceof CElementInfo && topci instanceof CElementInfo)
                ((CElementInfo)r).setSubstitutionHead((CElementInfo)topci);
        }

        return r;
    }

    @Override
    public CClassInfo empty(XSContentType ct ) { return null; }

    @Override
    public CClassInfo identityConstraint(XSIdentityConstraint xsIdentityConstraint) {
        return never();
    }

    @Override
    public CClassInfo xpath(XSXPath xsxPath) {
        return never();
    }

    @Override
    public CClassInfo attributeUse(XSAttributeUse use) {
        return never();
    }

    @Override
    public CElement simpleType(XSSimpleType type) {
        CElement c = allow(type,type.getName());
        if(c!=null) return c;

        if(getGlobalBinding().isSimpleTypeSubstitution() && type.isGlobal()) {
            return new CClassInfo(model,selector.getClassScope(),
                    deriveName(type), type.getLocator(), getName(type), null, type, null );
        }

        return never();
    }

    @Override
    public CClassInfo particle(XSParticle particle) {
        return never();
    }

    @Override
    public CClassInfo wildcard(XSWildcard wc) {
        return never();
    }


    // these methods won't be used
    @Override
    public CClassInfo annotation(XSAnnotation annon) {
        assert false;
        return null;
    }

    @Override
    public CClassInfo notation(XSNotation not) {
        assert false;
        return null;
    }

    @Override
    public CClassInfo facet(XSFacet decl) {
        assert false;
        return null;
    }
    @Override
    public CClassInfo schema(XSSchema schema) {
        assert false;
        return null;
    }





    /**
     * Makes sure that the component doesn't carry a {@link BIClass}
     * customization.
     *
     * @return
     *      return value is unused. Since most of the caller needs to
     *      return null, to make the code a little bit shorter, this
     *      method always return null (so that the caller can always
     *      say <code>return never(sc);</code>.
     */
    private CClassInfo never() {
        // all we need to do here is just not to acknowledge
        // any class customization. Then this class customization
        // will be reported as an error later when we check all
        // unacknowledged customizations.


//        BIDeclaration cust=owner.getBindInfo(component).get(BIClass.NAME);
//        if(cust!=null) {
//            // error
//            owner.errorReporter.error(
//                cust.getLocation(),
//                "test {0}", NameGetter.get(component) );
//        }
        return null;
    }

    /**
     * Checks if a component carries a customization to map it to a class.
     * If so, make it a class.
     *
     * @param defaultBaseName
     *      The token which will be used as the basis of the class name
     *      if the class name is not specified in the customization.
     *      This is usually the name of an element declaration, and so on.
     *
     *      This parameter can be null, in that case it would be an error
     *      if a name is not given by the customization.
     */
    private CElement allow( XSComponent component, String defaultBaseName ) {

        BIClass decl = null;

        if(component instanceof XSComplexType) {
            XSType complexType = (XSType)component;

            BIClass lastFoundRecursiveBiClass = null;

            if(complexType.getName() != null) {
                while( ! schemas.getAnyType().equals(complexType)) {
                    BindInfo bindInfo = builder.getBindInfo(complexType);
                    BIClass biClass = bindInfo.get(BIClass.class);

                    if(biClass != null && "true".equals(biClass.getRecursive()))
                        lastFoundRecursiveBiClass = biClass;

                    complexType = complexType.getBaseType();
                }
            }

            // use this as biclass for current component
            decl = lastFoundRecursiveBiClass;

        }

        BindInfo bindInfo = builder.getBindInfo(component);
        if(decl == null) {
            decl = bindInfo.get(BIClass.class);
            if(decl==null)  return null;
        }

        decl.markAsAcknowledged();

        // first consider binding to the class reference.
        String ref = decl.getExistingClassRef();
        if(ref!=null) {
            if(!JJavaName.isFullyQualifiedClassName(ref)) {
                Ring.get(ErrorReceiver.class).error( decl.getLocation(),
                    Messages.format(Messages.ERR_INCORRECT_CLASS_NAME,ref) );
                // recover by ignoring @ref
            } else {
                if(component instanceof XSComplexType) {
                    // UGLY UGLY UGLY
                    // since we are not going to bind this complex type, we need to figure out
                    // its binding mode without actually binding it (and also expose this otherwise
                    // hidden mechanism into this part of the code.)
                    //
                    // this code is potentially dangerous as the base class might have been bound
                    // in different ways. To be correct, we need to figure out how the content type
                    // would have been bound, from the schema.
                    Ring.get(ComplexTypeFieldBuilder.class).recordBindingMode(
                        (XSComplexType)component, ComplexTypeBindingMode.NORMAL
                    );
                }
                return new CClassRef(model, component, decl, bindInfo.toCustomizationList() );
            }
        }

        String clsName = decl.getClassName();
        if(clsName==null) {
            // if the customiztion doesn't give us a name, derive one
            // from the current component.
            if( defaultBaseName==null ) {
                Ring.get(ErrorReceiver.class).error( decl.getLocation(),
                    Messages.format(Messages.ERR_CLASS_NAME_IS_REQUIRED) );

                // recover by generating a pseudo-random name
                defaultBaseName = "undefined"+component.hashCode();
            }
            clsName = builder.deriveName( defaultBaseName, component );
        } else {
            if( !JJavaName.isJavaIdentifier(clsName) ) {
                // not a valid Java class name
                Ring.get(ErrorReceiver.class).error( decl.getLocation(),
                    Messages.format( Messages.ERR_INCORRECT_CLASS_NAME, clsName ));
                // recover by a dummy name
                clsName = "Undefined"+component.hashCode();
            }
        }

        QName typeName = null;
        QName elementName = null;

        if(component instanceof XSType) {
            XSType t = (XSType) component;
            typeName = getName(t);
        }

        if (component instanceof XSElementDecl) {
            XSElementDecl e = (XSElementDecl) component;
            elementName = getName(e);
        }

        if (component instanceof XSElementDecl && !isCollapsable((XSElementDecl)component)) {
            XSElementDecl e = ((XSElementDecl)component);

            CElementInfo cei = new CElementInfo(model, elementName,
                    selector.getClassScope(), clsName,
                    bindInfo.toCustomizationList(), decl.getLocation() );
            selector.boundElements.put(e,cei);

            stb.refererStack.push(component);    // referer is element
            cei.initContentType(
                selector.bindToType(e.getType(),e),
                e,e.getDefaultValue());
            stb.refererStack.pop();
            return cei;
            // TODO: support javadoc and userSpecifiedImplClass
        } else {
            CClassInfo bt = new CClassInfo(model,selector.getClassScope(),
                    clsName, decl.getLocation(), typeName, elementName, component, bindInfo.toCustomizationList() );

            // set javadoc class comment.
            if(decl.getJavadoc()!=null )
                bt.javadoc = decl.getJavadoc()+"\n\n";
                // add extra blank lines so that the schema fragment
                // and user-specified javadoc would be separated


            // if the implClass is given, set it to ClassItem
            String implClass = decl.getUserSpecifiedImplClass();
            if( implClass!=null )
                bt.setUserSpecifiedImplClass( implClass );

            return bt;
        }
    }

    private BIGlobalBinding getGlobalBinding() {
        return builder.getGlobalBinding();
    }

    /**
     * Derives a name from a schema component.
     * Use the name of the schema component as the default name.
     */
    private String deriveName( XSDeclaration comp ) {
        return builder.deriveName( comp.getName(), comp );
    }

    /**
     * Derives a name from a schema component.
     * For complex types, we take redefinition into account when
     * deriving a default name.
     */
    private String deriveName( XSComplexType comp ) {
        String seed = builder.deriveName( comp.getName(), comp );
        int cnt = comp.getRedefinedCount();
        for( ; cnt>0; cnt-- )
            seed = "Original"+seed;
        return seed;
    }

}
