/*
 * 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.
 */

package freemarker.ext.beans;

import freemarker.template.DefaultObjectWrapperBuilder;
import freemarker.template.ObjectWrapper;
import freemarker.template.TemplateDateModel;
import freemarker.template.Version;
import freemarker.template._TemplateAPI;

/**
 * Holds {@link BeansWrapper} configuration settings and defines their defaults.
 * You will not use this abstract class directly, but concrete subclasses like {@link BeansWrapperBuilder} and
 * {@link DefaultObjectWrapperBuilder}. Unless, you are developing a builder for a custom {@link BeansWrapper} subclass.
 * 
 * <p>This class is designed so that its instances can be used as lookup keys in a singleton cache. This is also why
 * this class defines the configuration setting defaults for {@link BeansWrapper}, instead of leaving that to
 * {@link BeansWrapper} itself. (Because, the default values influence the lookup key, and the singleton needs to be
 * looked up without creating a {@link BeansWrapper} instance.) However, because instances are mutable, you should
 * deep-clone it with {@link #clone(boolean)} before using it as cache key.
 * 
 * @since 2.3.21
 */
public abstract class BeansWrapperConfiguration implements Cloneable {

    private final Version incompatibleImprovements;
    
    private ClassIntrospectorBuilder classIntrospectorBuilder;
    
    // Properties and their *defaults*:
    private boolean simpleMapWrapper = false;
    private boolean preferIndexedReadMethod;
    private int defaultDateType = TemplateDateModel.UNKNOWN;
    private ObjectWrapper outerIdentity = null;
    private boolean strict = false;
    private boolean useModelCache = false;
    // Attention!
    // - As this object is a cache key, non-normalized field values should be avoided.
    // - Fields with default values must be set until the end of the constructor to ensure that when the lookup happens,
    //   there will be no unset fields.
    // - If you add a new field, review all methods in this class
    
    /**
     * @param incompatibleImprovements
     *            See the corresponding parameter of {@link BeansWrapper#BeansWrapper(Version)}. Not {@code null}. Note
     *            that the version will be normalized to the lowest version where the same incompatible
     *            {@link BeansWrapper} improvements were already present, so for the returned instance
     *            {@link #getIncompatibleImprovements()} might returns a lower version than what you have specified
     *            here.
     * @param isIncompImprsAlreadyNormalized
     *            Tells if the {@code incompatibleImprovements} parameter contains an <em>already normalized</em> value.
     *            This parameter meant to be {@code true} when the class that extends {@link BeansWrapper} needs to add
     *            additional breaking versions over those of {@link BeansWrapper}. Thus, if this parameter is
     *            {@code true}, the versions where {@link BeansWrapper} had breaking changes must be already factored
     *            into the {@code incompatibleImprovements} parameter value, as no more normalization will happen. (You
     *            can use {@link BeansWrapper#normalizeIncompatibleImprovementsVersion(Version)} to discover those.)
     * 
     * @since 2.3.22
     */
    protected BeansWrapperConfiguration(Version incompatibleImprovements, boolean isIncompImprsAlreadyNormalized) {
        _TemplateAPI.checkVersionNotNullAndSupported(incompatibleImprovements);
        
        incompatibleImprovements = isIncompImprsAlreadyNormalized
                ? incompatibleImprovements
                : BeansWrapper.normalizeIncompatibleImprovementsVersion(incompatibleImprovements);
        this.incompatibleImprovements = incompatibleImprovements;
        
        preferIndexedReadMethod = incompatibleImprovements.intValue() < _TemplateAPI.VERSION_INT_2_3_27;
        
        classIntrospectorBuilder = new ClassIntrospectorBuilder(incompatibleImprovements);
    }
    
    /**
     * Same as {@link #BeansWrapperConfiguration(Version, boolean) BeansWrapperConfiguration(Version, false)}.
     */
    protected BeansWrapperConfiguration(Version incompatibleImprovements) {
        this(incompatibleImprovements, false);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + incompatibleImprovements.hashCode();
        result = prime * result + (simpleMapWrapper ? 1231 : 1237);
        result = prime * result + (preferIndexedReadMethod ? 1231 : 1237);
        result = prime * result + defaultDateType;
        result = prime * result + (outerIdentity != null ? outerIdentity.hashCode() : 0);
        result = prime * result + (strict ? 1231 : 1237);
        result = prime * result + (useModelCache ? 1231 : 1237);
        result = prime * result + classIntrospectorBuilder.hashCode();
        return result;
    }

    /**
     * Two {@link BeansWrapperConfiguration}-s are equal exactly if their classes are identical ({@code ==}), and their
     * field values are equal.
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        BeansWrapperConfiguration other = (BeansWrapperConfiguration) obj;
        
        if (!incompatibleImprovements.equals(other.incompatibleImprovements)) return false;
        if (simpleMapWrapper != other.simpleMapWrapper) return false;
        if (preferIndexedReadMethod != other.preferIndexedReadMethod) return false;
        if (defaultDateType != other.defaultDateType) return false;
        if (outerIdentity != other.outerIdentity) return false;
        if (strict != other.strict) return false;
        if (useModelCache != other.useModelCache) return false;
        if (!classIntrospectorBuilder.equals(other.classIntrospectorBuilder)) return false;
        
        return true;
    }
    
    protected Object clone(boolean deepCloneKey) {
        try {
            BeansWrapperConfiguration clone = (BeansWrapperConfiguration) super.clone();
            if (deepCloneKey) {
                clone.classIntrospectorBuilder
                        = (ClassIntrospectorBuilder) classIntrospectorBuilder.clone();
            }
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("Failed to clone BeansWrapperConfiguration", e);
        }
    }
    
    public boolean isSimpleMapWrapper() {
        return simpleMapWrapper;
    }

    /** See {@link BeansWrapper#setSimpleMapWrapper(boolean)}. */
    public void setSimpleMapWrapper(boolean simpleMapWrapper) {
        this.simpleMapWrapper = simpleMapWrapper;
    }
    
    /** @since 2.3.27 */
    public boolean getPreferIndexedReadMethod() {
        return preferIndexedReadMethod;
    }

    /** See {@link BeansWrapper#setPreferIndexedReadMethod(boolean)}. @since 2.3.27 */
    public void setPreferIndexedReadMethod(boolean preferIndexedReadMethod) {
        this.preferIndexedReadMethod = preferIndexedReadMethod;
    }

    public int getDefaultDateType() {
        return defaultDateType;
    }

    /** See {@link BeansWrapper#setDefaultDateType(int)}. */
    public void setDefaultDateType(int defaultDateType) {
        this.defaultDateType = defaultDateType;
    }

    public ObjectWrapper getOuterIdentity() {
        return outerIdentity;
    }

    /**
     * See {@link BeansWrapper#setOuterIdentity(ObjectWrapper)}, except here the default is {@code null} that means
     * the {@link ObjectWrapper} that you will set up with this {@link BeansWrapperBuilder} object.
     */
    public void setOuterIdentity(ObjectWrapper outerIdentity) {
        this.outerIdentity = outerIdentity;
    }

    public boolean isStrict() {
        return strict;
    }

    /** See {@link BeansWrapper#setStrict(boolean)}. */
    public void setStrict(boolean strict) {
        this.strict = strict;
    }

    public boolean getUseModelCache() {
        return useModelCache;
    }

    /** See {@link BeansWrapper#setUseCache(boolean)} (it means the same). */
    public void setUseModelCache(boolean useModelCache) {
        this.useModelCache = useModelCache;
    }

    public Version getIncompatibleImprovements() {
        return incompatibleImprovements;
    }
    
    public int getExposureLevel() {
        return classIntrospectorBuilder.getExposureLevel();
    }

    /** See {@link BeansWrapper#setExposureLevel(int)}. */
    public void setExposureLevel(int exposureLevel) {
        classIntrospectorBuilder.setExposureLevel(exposureLevel);
    }

    public boolean getExposeFields() {
        return classIntrospectorBuilder.getExposeFields();
    }

    /** See {@link BeansWrapper#setExposeFields(boolean)}. */
    public void setExposeFields(boolean exposeFields) {
        classIntrospectorBuilder.setExposeFields(exposeFields);
    }

    public MemberAccessPolicy getMemberAccessPolicy() {
        return classIntrospectorBuilder.getMemberAccessPolicy();
    }

    public void setMemberAccessPolicy(MemberAccessPolicy memberAccessPolicy) {
        classIntrospectorBuilder.setMemberAccessPolicy(memberAccessPolicy);
    }

    public boolean getTreatDefaultMethodsAsBeanMembers() {
        return classIntrospectorBuilder.getTreatDefaultMethodsAsBeanMembers();
    }

    /** See {@link BeansWrapper#setTreatDefaultMethodsAsBeanMembers(boolean)} */
    public void setTreatDefaultMethodsAsBeanMembers(boolean treatDefaultMethodsAsBeanMembers) {
        classIntrospectorBuilder.setTreatDefaultMethodsAsBeanMembers(treatDefaultMethodsAsBeanMembers);
    }

    public MethodAppearanceFineTuner getMethodAppearanceFineTuner() {
        return classIntrospectorBuilder.getMethodAppearanceFineTuner();
    }

    /**
     * See {@link BeansWrapper#setMethodAppearanceFineTuner(MethodAppearanceFineTuner)}; additionally,
     * note that currently setting this to non-{@code null} will disable class introspection cache sharing, unless
     * the value implements {@link SingletonCustomizer}.
     */
    public void setMethodAppearanceFineTuner(MethodAppearanceFineTuner methodAppearanceFineTuner) {
        classIntrospectorBuilder.setMethodAppearanceFineTuner(methodAppearanceFineTuner);
    }

    MethodSorter getMethodSorter() {
        return classIntrospectorBuilder.getMethodSorter();
    }

    void setMethodSorter(MethodSorter methodSorter) {
        classIntrospectorBuilder.setMethodSorter(methodSorter);
    }

    ClassIntrospectorBuilder getClassIntrospectorBuilder() {
        return classIntrospectorBuilder;
    }
 
}
