/*
 * Copyright (c) 1997, 2022 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.bindinfo;

import java.util.Collection;
import java.util.Collections;

import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElementRef;
import jakarta.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;

import com.sun.codemodel.JJavaName;
import com.sun.codemodel.JType;
import com.sun.tools.xjc.ErrorReceiver;
import com.sun.tools.xjc.generator.bean.field.FieldRenderer;
import com.sun.tools.xjc.generator.bean.field.FieldRendererFactory;
import com.sun.tools.xjc.generator.bean.field.IsSetFieldRenderer;
import com.sun.tools.xjc.model.CAttributePropertyInfo;
import com.sun.tools.xjc.model.CCustomizations;
import com.sun.tools.xjc.model.CElementPropertyInfo;
import com.sun.tools.xjc.model.CPropertyInfo;
import com.sun.tools.xjc.model.CReferencePropertyInfo;
import com.sun.tools.xjc.model.CValuePropertyInfo;
import com.sun.tools.xjc.model.TypeUse;
import com.sun.tools.xjc.reader.Const;
import com.sun.tools.xjc.reader.RawTypeSet;
import com.sun.tools.xjc.reader.Ring;
import com.sun.tools.xjc.reader.TypeUtil;
import com.sun.tools.xjc.reader.xmlschema.BGMBuilder;
import org.glassfish.jaxb.core.api.impl.NameConverter;
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.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.XSSimpleType;
import com.sun.xml.xsom.XSWildcard;
import com.sun.xml.xsom.XSXPath;
import com.sun.xml.xsom.util.XSFinder;
import com.sun.xml.xsom.visitor.XSFunction;

import org.xml.sax.Locator;

/**
 * Property customization.
 * 
 * This customization turns an arbitrary schema component
 * into a Java property (some restrictions apply.)
 * 
 * <p>
 * All the getter methods (such as <code>getBaseType</code> or
 * <code>getBindStyle</code>) honors the delegation chain of
 * property customization specified in the spec. Namely,
 * if two property customizations are attached to an attribute
 * use and an attribute decl, then anything unspecified in the
 * attribute use defaults to attribute decl.
 * 
 * <p>
 * Property customizations are acknowledged
 * (1) when they are actually used, and
 * (2) when they are given at the component, which is mapped to a class.
 *     (so-called "point of declaration" customization)
 * 
 * @author
 *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
 */
@XmlRootElement(name="property")
public final class BIProperty extends AbstractDeclarationImpl {
    
    // can be null
    @XmlAttribute
    private String name = null;
    
    // can be null
    @XmlElement
    private String javadoc = null;
    
    // can be null
    @XmlElement
    private BaseTypeBean baseType = null;

    // TODO: report 'unsupported' error if this is true
    @XmlAttribute
    private boolean generateFailFastSetterMethod = false;



    public BIProperty(Locator loc, String _propName, String _javadoc,
                      BaseTypeBean _baseType, CollectionTypeAttribute collectionType, Boolean isConst,
                      OptionalPropertyMode optionalProperty, Boolean genElemProp) {
        super(loc);

        this.name = _propName;
        this.javadoc = _javadoc;
        this.baseType = _baseType;
        this.collectionType = collectionType;
        this.isConstantProperty = isConst;
        this.optionalProperty = optionalProperty;
        this.generateElementProperty = genElemProp;
    }

    protected BIProperty() {}

    @Override
    public Collection<BIDeclaration> getChildren() {
        BIConversion conv = getConv();
        if(conv==null)
            return super.getChildren();
        else
            return Collections.singleton(conv);
    }

    @Override
    public void setParent( BindInfo parent ) {
        super.setParent(parent);
        if(baseType!=null && baseType.conv!=null)
            baseType.conv.setParent(parent);
    }

    
    
    /**
     * Returns the customized property name.
     * 
     * This method honors the "enableJavaNamingConvention" customization
     * and formats the property name accordingly if necessary.
     * 
     * Thus the caller should <em>NOT</em> apply the XML-to-Java name
     * conversion algorithm to the value returned from this method.
     * 
     * @param forConstant
     *      If the property name is intended for a constant property name,
     *      set to true. This will change the result
     * 
     * @return
     *      This method can return null if the customization doesn't
     *      specify the name.
     */
    public String getPropertyName( boolean forConstant ) {
        if(name!=null) {
            BIGlobalBinding gb = getBuilder().getGlobalBinding();
            NameConverter nc = getBuilder().model.getNameConverter();

            if( gb.isJavaNamingConventionEnabled() && !forConstant )
                // apply XML->Java conversion
                return nc.toPropertyName(name);
            else
                return name;    // ... or don't change the value
        }
        BIProperty next = getDefault();
        if(next!=null)  return next.getPropertyName(forConstant);
        else            return null;
    }
    
    /**
     * Gets the associated javadoc.
     * 
     * @return
     *      null if none is specfieid.
     */
    public String getJavadoc() {
        return javadoc;
    }
    
    // can be null
    public JType getBaseType() {
        if(baseType!=null && baseType.name!=null) {
            return TypeUtil.getType(getCodeModel(),
                    baseType.name,
                    Ring.get(ErrorReceiver.class),getLocation());
        }
        BIProperty next = getDefault();
        if(next!=null)  return next.getBaseType();
        else            return null;
    }
    
    
    // can be null
    @XmlAttribute
    private CollectionTypeAttribute collectionType = null;

    /**
     * Gets the realization of this field.
     * @return Always return non-null.
     */
    CollectionTypeAttribute getCollectionType() {
        if(collectionType!=null)   return collectionType;
        return getDefault().getCollectionType();
    }


    @XmlAttribute
    private OptionalPropertyMode optionalProperty = null;

    // virtual property for @generateIsSetMethod
    @XmlAttribute
    void setGenerateIsSetMethod(boolean b) {
        optionalProperty = b ? OptionalPropertyMode.ISSET : OptionalPropertyMode.WRAPPER;
    }

    public OptionalPropertyMode getOptionalPropertyMode() {
        if(optionalProperty!=null)   return optionalProperty;
        return getDefault().getOptionalPropertyMode();
    }

    // null if delegated
    @XmlAttribute
    private Boolean generateElementProperty = null;
    /**
     * If true, the property will automatically be a reference property.
     * (Talk about confusing names!)
     */
    private Boolean generateElementProperty() {
        if(generateElementProperty!=null)   return generateElementProperty;
        BIProperty next = getDefault();
        if(next!=null)      return next.generateElementProperty();

        return null;
    }


    // true, false, or null (which means the value should be inherited.)
    @XmlAttribute(name="fixedAttributeAsConstantProperty")
    private Boolean isConstantProperty;
    /**
     * Gets the inherited value of the "fixedAttrToConstantProperty" customization.
     * 
     * <p>
     * Note that returning true from this method doesn't necessarily mean
     * that a property needs to be mapped to a constant property.
     * It just means that it's mapped to a constant property
     * <b>if an attribute use carries a fixed value.</b>
     * 
     * <p>
     * I don't like this semantics but that's what the spec implies.
     */
    public boolean isConstantProperty() {
        if(isConstantProperty!=null)    return isConstantProperty;
        
        BIProperty next = getDefault();
        if(next!=null)      return next.isConstantProperty();
        
        // globalBinding always has true or false in this property,
        // so this can't happen
        throw new AssertionError();
    }

    public CValuePropertyInfo createValueProperty(String defaultName,boolean forConstant,
        XSComponent source,TypeUse tu, QName typeName) {

        markAsAcknowledged();
        constantPropertyErrorCheck();

        String name = getPropertyName(forConstant);
        if(name==null) {
            name = defaultName;
            if(tu.isCollection() && getBuilder().getGlobalBinding().isSimpleMode())
                name = JJavaName.getPluralForm(name);
        }

        CValuePropertyInfo prop = wrapUp(new CValuePropertyInfo(name, source, getCustomizations(source), source.getLocator(), tu, typeName), source);
        BIInlineBinaryData.handle(source, prop);
        return prop;
    }

    public CAttributePropertyInfo createAttributeProperty( XSAttributeUse use, TypeUse tu ) {

        boolean forConstant =
            getCustomization(use).isConstantProperty() &&
            use.getFixedValue()!=null;

        String name = getPropertyName(forConstant);
        if(name==null) {
            NameConverter conv = getBuilder().getNameConverter();
            if(forConstant)
                name = conv.toConstantName(use.getDecl().getName());
            else
                name = conv.toPropertyName(use.getDecl().getName());
            if(tu.isCollection() && getBuilder().getGlobalBinding().isSimpleMode())
                name = JJavaName.getPluralForm(name);
        }

        markAsAcknowledged();
        constantPropertyErrorCheck();

        return wrapUp(new CAttributePropertyInfo(name,use,getCustomizations(use),use.getLocator(),
                BGMBuilder.getName(use.getDecl()), tu,
                BGMBuilder.getName(use.getDecl().getType()), use.isRequired() ),use);
    }

    /**
     * 
     *
     * @param defaultName
     *      If the name is not customized, this name will be used
     *      as the default. Note that the name conversion <b>MUST</b>
     *      be applied before this method is called if necessary.
     * @param source
     *      Source schema component from which a field is built.
     */
    public CElementPropertyInfo createElementProperty(String defaultName, boolean forConstant, XSParticle source,
                                                      RawTypeSet types) {

        if(!types.refs.isEmpty())
            // if this property is empty, don't acknowleedge the customization
            // this allows pointless property customization to be reported as an error
            markAsAcknowledged();
        constantPropertyErrorCheck();

        String name = getPropertyName(forConstant);
        if(name==null)
            name = defaultName;

        CElementPropertyInfo prop = wrapUp(
            new CElementPropertyInfo(
                name, types.getCollectionMode(),
                types.id(),
                types.getExpectedMimeType(),
                source, getCustomizations(source),
                source.getLocator(), types.isRequired()),
            source);

        types.addTo(prop);

        BIInlineBinaryData.handle(source.getTerm(), prop);
        return prop;
    }

    public CReferencePropertyInfo createDummyExtendedMixedReferenceProperty(
            String defaultName, XSComponent source, RawTypeSet types) {
            return createReferenceProperty(
                    defaultName,
                    false,
                    source,
                    types,
                    true,
                    true,
                    false,
                    true);
    }

    public CReferencePropertyInfo createContentExtendedMixedReferenceProperty(
            String defaultName, XSComponent source, RawTypeSet types) {
            return createReferenceProperty(
                    defaultName,
                    false,
                    source,
                    types,
                    true,
                    false,
                    true,
                    true);
    }

    public CReferencePropertyInfo createReferenceProperty(
            String defaultName, boolean forConstant, XSComponent source,
            RawTypeSet types, boolean isMixed, boolean dummy, boolean content, boolean isMixedExtended) {

        if (types == null) {    // this is a special case where we need to generate content because potential subtypes would need to be able to override what's store inside
            content = true;
        } else {
            if(!types.refs.isEmpty())
                // if this property is empty, don't acknowleedge the customization
                // this allows pointless property customization to be reported as an error
                markAsAcknowledged();
        }
        constantPropertyErrorCheck();
        
        String name = getPropertyName(forConstant);
        if(name==null)
            name = defaultName;

        CReferencePropertyInfo prop = wrapUp(
                                            new CReferencePropertyInfo(
                                                name,
                                                    types == null || types.getCollectionMode().isRepeated() || isMixed,
                                                    types != null && types.isRequired(),
                                                isMixed,
                                                source,
                                                getCustomizations(source), source.getLocator(), dummy, content, isMixedExtended),
                                        source);
        if (types != null) {
            types.addTo(prop);
        }

        BIInlineBinaryData.handle(source, prop);
        return prop;
    }

    public CPropertyInfo createElementOrReferenceProperty(
            String defaultName, boolean forConstant, XSParticle source,
            RawTypeSet types) {

        boolean generateRef;

        switch(types.canBeTypeRefs) {
        case CAN_BE_TYPEREF:
        case SHOULD_BE_TYPEREF:
            // it's up to the use
            Boolean b = generateElementProperty();
            if(b==null) // follow XJC recommendation
                generateRef = types.canBeTypeRefs== RawTypeSet.Mode.CAN_BE_TYPEREF;
            else // use the value user gave us
                generateRef = b;
            break;
        case MUST_BE_REFERENCE:
            generateRef = true;
            break;
        default:
            throw new AssertionError();
        }

        if(generateRef) {
            return createReferenceProperty(defaultName,forConstant,source,types, false, false, false, false);
        } else {
            return createElementProperty(defaultName,forConstant,source,types);
        }
    }

    /**
     * Common finalization of {@link CPropertyInfo} for the create***Property methods.
     */
    private <T extends CPropertyInfo> T wrapUp(T prop, XSComponent source) {
        prop.javadoc = concat(javadoc,
            getBuilder().getBindInfo(source).getDocumentation());
        if(prop.javadoc==null)
            prop.javadoc="";

        // decide the realization.
        FieldRenderer r;
        OptionalPropertyMode opm = getOptionalPropertyMode();
        if(prop.isCollection()) {
            CollectionTypeAttribute ct = getCollectionType();
            r = ct.get(getBuilder().model);
        } else {
            FieldRendererFactory frf = getBuilder().fieldRendererFactory;
            // according to the spec we should bahave as in jaxb1. So we ignore possiblity that property could be nullable
            switch(opm) {
                // the property type can be primitive type if we are to ignore absence
                case PRIMITIVE:
                    r = frf.getRequiredUnboxed();
                    break;
                case WRAPPER:
                    // force the wrapper type
                    r = prop.isOptionalPrimitive() ? frf.getSingle() : frf.getDefault();
                    break;
                case ISSET:
                    r = prop.isOptionalPrimitive() ? frf.getSinglePrimitiveAccess() : frf.getDefault();
                    break;
                default:
                    throw new Error();

            }
        }
        if(opm==OptionalPropertyMode.ISSET) {
            // only isSet is allowed on a collection. these 3 modes aren't really symmetric.

            // if the property is a primitive type, we need an explicit unset because
            // we can't overload the meaning of set(null).
            // if it's a collection, we need to be able to unset it so that we can distinguish
            // null list and empty list.
            r = new IsSetFieldRenderer( r, prop.isOptionalPrimitive()||prop.isCollection(), true );
        }

        prop.realization = r;

        JType bt = getBaseType();
        if(bt!=null)
            prop.baseType = bt;

        return prop;
    }

    private CCustomizations getCustomizations( XSComponent src ) {
        return getBuilder().getBindInfo(src).toCustomizationList();
    }

    private CCustomizations getCustomizations( XSComponent... src ) {
        CCustomizations c = null;
        for (XSComponent s : src) {
            CCustomizations r = getCustomizations(s);
            if(c==null)     c = r;
            else            c = CCustomizations.merge(c,r);
        }
        return c;
    }

    private CCustomizations getCustomizations( XSAttributeUse src ) {
        // customizations for an attribute use should include those defined in the local attribute.
        // this is so that the schema like:
        //
        // <xs:attribute name="foo" type="xs:int">
        //   <xs:annotation><xs:appinfo>
        //     <hyperjaxb:... />
        //
        // would be picked up
        if(src.getDecl().isLocal())
            return getCustomizations(src,src.getDecl());
        else
            return getCustomizations((XSComponent)src);
    }

    private CCustomizations getCustomizations( XSParticle src ) {
        // customizations for a particle  should include those defined in the term unless it's global
        // this is so that the schema like:
        //
        // <xs:sequence>
        //   <xs:element name="foo" type="xs:int">
        //     <xs:annotation><xs:appinfo>
        //       <hyperjaxb:... />
        //
        // would be picked up
        if(src.getTerm().isElementDecl()) {
            XSElementDecl xed = src.getTerm().asElementDecl();
            if(xed.isGlobal())
                return getCustomizations((XSComponent)src);
        }

        return getCustomizations(src,src.getTerm());
    }



    @Override
    public void markAsAcknowledged() {
        if( isAcknowledged() )  return;
        
        // mark the parent as well.
        super.markAsAcknowledged();
        
        BIProperty def = getDefault();
        if(def!=null)   def.markAsAcknowledged();
    }
    
    private void constantPropertyErrorCheck() {
        if( isConstantProperty!=null && getOwner()!=null ) {
            // run additional check on the isCOnstantProperty value.
            // this value is not allowed if the schema component doesn't have
            // a fixed value constraint.
            //
            // the setParent method associates a customization with the rest of
            // XSOM object graph, so this is the earliest possible moment where
            // we can test this.
            
            if( !hasFixedValue.find(getOwner()) ) {
                Ring.get(ErrorReceiver.class).error(
                    getLocation(),
                    Messages.ERR_ILLEGAL_FIXEDATTR.format()
                );
                // set this value to null to avoid the same error to be reported more than once.
                isConstantProperty = null;
            }
        }
    }

    /**
     * Function object that returns true if a component has
     * a fixed value constraint.
     */
    private final XSFinder hasFixedValue = new XSFinder() {
        @Override
        public Boolean attributeDecl(XSAttributeDecl decl) {
            return decl.getFixedValue()!=null;
        }

        @Override
        public Boolean attributeUse(XSAttributeUse use) {
            return use.getFixedValue()!=null;
        }
        
        @Override
        public Boolean schema(XSSchema s) {
            // we allow globalBindings to have isConstantProperty==true,
            // so this method returns true to allow this.
            return true;
        }
    };
    
    /**
     * Finds a BIProperty which this object should delegate to.
     * 
     * @return
     *      always return non-null for normal BIProperties.
     *      If this object is contained in the BIGlobalBinding, then
     *      this method returns null to indicate that there's no more default.
     */
    protected BIProperty getDefault() {
        if(getOwner()==null)    return null;
        BIProperty next = getDefault(getBuilder(),getOwner());
        if(next==this)  return null;    // global.
        else            return next;
    }
    
    private static BIProperty getDefault( BGMBuilder builder, XSComponent c ) {
        while(c!=null) {
            c = c.apply(defaultCustomizationFinder);
            if(c!=null) {
                BIProperty prop = builder.getBindInfo(c).get(BIProperty.class);
                if(prop!=null)  return prop;
            }
        }
        
        // default to the global one
        return builder.getGlobalBinding().getDefaultProperty();
    }
    
    
    /**
     * Finds a property customization that describes how the given
     * component should be mapped to a property (if it's mapped to
     * a property at all.)
     * 
     * <p>
     * Consider an attribute use that does NOT carry a property
     * customization. This schema component is nonetheless considered
     * to carry a (sort of) implicit property customization, whose values
     * are defaulted.
     * 
     * <p>
     * This method can be think of the method that returns this implied
     * property customization.
     * 
     * <p>
     * Note that this doesn't mean the given component needs to be
     * mapped to a property. But if it does map to a property, it needs
     * to follow this customization.
     * 
     * I think this semantics is next to non-sense but I couldn't think
     * of any other way to follow the spec.
     * 
     * @param c
     *      A customization effective on this component will be returned.
     *      Can be null just to get the global customization.
     * @return
     *      Always return non-null valid object.
     */
    public static BIProperty getCustomization( XSComponent c ) {
        BGMBuilder builder = Ring.get(BGMBuilder.class);

        // look for a customization on this component
        if( c!=null ) {
            BIProperty prop = builder.getBindInfo(c).get(BIProperty.class);
            if(prop!=null)  return prop;
        }
        
        // if no such thing exists, defeault.
        return getDefault(builder,c);
    }
    
    private final static XSFunction<XSComponent> defaultCustomizationFinder = new XSFunction<>() {

        @Override
        public XSComponent attributeUse(XSAttributeUse use) {
            return use.getDecl();   // inherit from the declaration
        }

        @Override
        public XSComponent particle(XSParticle particle) {
            return particle.getTerm(); // inherit from the term
        }

        @Override
        public XSComponent schema(XSSchema schema) {
            // no more delegation
            return null;
        }

        // delegates to the context schema object
        @Override
        public XSComponent attributeDecl(XSAttributeDecl decl) {
            return decl.getOwnerSchema();
        }

        @Override
        public XSComponent wildcard(XSWildcard wc) {
            return wc.getOwnerSchema();
        }

        @Override
        public XSComponent modelGroupDecl(XSModelGroupDecl decl) {
            return decl.getOwnerSchema();
        }

        @Override
        public XSComponent modelGroup(XSModelGroup group) {
            return group.getOwnerSchema();
        }

        @Override
        public XSComponent elementDecl(XSElementDecl decl) {
            return decl.getOwnerSchema();
        }

        @Override
        public XSComponent complexType(XSComplexType type) {
            return type.getOwnerSchema();
        }

        @Override
        public XSComponent simpleType(XSSimpleType st) {
            return st.getOwnerSchema();
        }

        // property customizations are not allowed on these components.
        @Override
        public XSComponent attGroupDecl(XSAttGroupDecl decl) {
            throw new IllegalStateException();
        }

        @Override
        public XSComponent empty(XSContentType empty) {
            throw new IllegalStateException();
        }

        @Override
        public XSComponent annotation(XSAnnotation xsAnnotation) {
            throw new IllegalStateException();
        }

        @Override
        public XSComponent facet(XSFacet xsFacet) {
            throw new IllegalStateException();
        }

        @Override
        public XSComponent notation(XSNotation xsNotation) {
            throw new IllegalStateException();
        }

        @Override
        public XSComponent identityConstraint(XSIdentityConstraint x) {
            throw new IllegalStateException();
        }

        @Override
        public XSComponent xpath(XSXPath xsxPath) {
            throw new IllegalStateException();
        }
    };
    
    
    private static String concat( String s1, String s2 ) {
        if(s1==null)    return s2;
        if(s2==null)    return s1;
        return s1+"\n\n"+s2;
    }
    
    @Override
    public QName getName() { return NAME; }
    
    /** Name of this declaration. */
    public static final QName NAME = new QName(
        Const.JAXB_NSURI, "property" );

    public BIConversion getConv() {
        if(baseType!=null)
            return baseType.conv;
        else
            return null;
    }

    public static final class BaseTypeBean {
        public BaseTypeBean() {}
        /**
         * If there's a nested javaType customization, this field
         * will keep that customization. Otherwise null.
         *
         * This customization, if present, is used to customize
         * the simple type mapping at the point of reference.
         */
        @XmlElementRef
        BIConversion conv;

        /**
         * Java type name.
         */
        @XmlAttribute
        String name;
    }
}

