/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * Licensed 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 org.onosproject.yangutils.datamodel;

import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.linker.impl.ResolvableStatus;
import com.google.common.base.Strings;

import static org.onosproject.yangutils.datamodel.YangDataTypes.BINARY;
import static org.onosproject.yangutils.datamodel.YangDataTypes.BITS;
import static org.onosproject.yangutils.datamodel.YangDataTypes.BOOLEAN;
import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
import static org.onosproject.yangutils.datamodel.YangDataTypes.EMPTY;
import static org.onosproject.yangutils.datamodel.YangDataTypes.ENUMERATION;
import static org.onosproject.yangutils.datamodel.YangDataTypes.IDENTITYREF;
import static org.onosproject.yangutils.datamodel.YangDataTypes.LEAFREF;
import static org.onosproject.yangutils.datamodel.YangDataTypes.STRING;
import static org.onosproject.yangutils.datamodel.YangDataTypes.UNION;
import static org.onosproject.yangutils.linker.impl.ResolvableStatus.INTRA_FILE_RESOLVED;
import static org.onosproject.yangutils.linker.impl.ResolvableStatus.RESOLVED;
import static org.onosproject.yangutils.utils.RestrictionResolver.isOfRangeRestrictedType;
import static org.onosproject.yangutils.utils.RestrictionResolver.processLengthRestriction;
import static org.onosproject.yangutils.utils.RestrictionResolver.processRangeRestriction;

/**
 * Represents the derived information.
 *
 * @param <T> extended information.
 */
public class YangDerivedInfo<T> implements LocationInfo {

    /**
     * YANG typedef reference.
     */
    private YangTypeDef referredTypeDef;

    /**
     * Resolved additional information about data type after linking, example
     * restriction info, named values, etc. The extra information is based
     * on the data type. Based on the data type, the extended info can vary.
     */
    private T resolvedExtendedInfo;

    /**
     * Line number of pattern restriction in YANG file.
     */
    private int lineNumber;

    /**
     * Position of pattern restriction in line.
     */
    private int charPositionInLine;

    /**
     * Effective built-in type, requried in case type of typedef is again a
     * derived type. This information is to be added during linking.
     */
    private YangDataTypes effectiveBuiltInType;

    /**
     * Length restriction string to temporary store the length restriction when the type
     * is derived.
     */
    private String lengthRestrictionString;

    /**
     * Range restriction string to temporary store the range restriction when the type
     * is derived.
     */
    private String rangeRestrictionString;

    /**
     * Pattern restriction string to  temporary store the pattern restriction when the type
     * is derived.
     */
    private YangPatternRestriction patternRestriction;

    /**
     * Returns the referred typedef reference.
     *
     * @return referred typedef reference
     */
    public YangTypeDef getReferredTypeDef() {
        return referredTypeDef;
    }

    /**
     * Sets the referred typedef reference.
     *
     * @param referredTypeDef referred typedef reference
     */
    public void setReferredTypeDef(YangTypeDef referredTypeDef) {
        this.referredTypeDef = referredTypeDef;
    }

    /**
     * Returns resolved extended information after successful linking.
     *
     * @return resolved extended information
     */
    public T getResolvedExtendedInfo() {
        return resolvedExtendedInfo;
    }

    /**
     * Sets resolved extended information after successful linking.
     *
     * @param resolvedExtendedInfo resolved extended information
     */
    public void setResolvedExtendedInfo(T resolvedExtendedInfo) {
        this.resolvedExtendedInfo = resolvedExtendedInfo;
    }

    @Override
    public int getLineNumber() {
        return lineNumber;
    }

    @Override
    public int getCharPosition() {
        return charPositionInLine;
    }

    @Override
    public void setLineNumber(int lineNumber) {
        this.lineNumber = lineNumber;
    }

    @Override
    public void setCharPosition(int charPositionInLine) {
        this.charPositionInLine = charPositionInLine;
    }

    /**
     * Returns the length restriction string.
     *
     * @return the length restriction string
     */
    public String getLengthRestrictionString() {
        return lengthRestrictionString;
    }

    /**
     * Sets the length restriction string.
     *
     * @param lengthRestrictionString the length restriction string
     */
    public void setLengthRestrictionString(String lengthRestrictionString) {
        this.lengthRestrictionString = lengthRestrictionString;
    }

    /**
     * Returns the range restriction string.
     *
     * @return the range restriction string
     */
    public String getRangeRestrictionString() {
        return rangeRestrictionString;
    }

    /**
     * Sets the range restriction string.
     *
     * @param rangeRestrictionString the range restriction string
     */
    public void setRangeRestrictionString(String rangeRestrictionString) {
        this.rangeRestrictionString = rangeRestrictionString;
    }

    /**
     * Returns the pattern restriction.
     *
     * @return the pattern restriction
     */
    public YangPatternRestriction getPatternRestriction() {
        return patternRestriction;
    }

    /**
     * Sets the pattern restriction.
     *
     * @param patternRestriction the pattern restriction
     */
    public void setPatternRestriction(YangPatternRestriction patternRestriction) {
        this.patternRestriction = patternRestriction;
    }

    /**
     * Returns effective built-in type.
     *
     * @return effective built-in type
     */
    public YangDataTypes getEffectiveBuiltInType() {
        return effectiveBuiltInType;
    }

    /**
     * Sets effective built-in type.
     *
     * @param effectiveBuiltInType effective built-in type
     */
    public void setEffectiveBuiltInType(YangDataTypes effectiveBuiltInType) {
        this.effectiveBuiltInType = effectiveBuiltInType;
    }

    /**
     * Resolves the type derived info, by obtaining the effective built-in type
     * and resolving the restrictions.
     *
     * @return resolution status
     * @throws DataModelException a violation in data mode rule
     */
    public ResolvableStatus resolve() throws DataModelException {

        YangType<?> baseType = getReferredTypeDef().getTypeDefBaseType();

        /*
         * Checks the data type of the referred typedef, if it's derived,
         * obtain effective built-in type and restrictions from it's derived
         * info, otherwise take from the base type of type itself.
         */
        if (baseType.getDataType() == DERIVED) {
            /*
             * Check whether the referred typedef is resolved.
             */
            if (baseType.getResolvableStatus() != INTRA_FILE_RESOLVED && baseType.getResolvableStatus() != RESOLVED) {
                throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
            }

            /*
             * Check if the referred typedef is intra file resolved, if yes sets
             * current status also to intra file resolved .
             */
            if (getReferredTypeDef().getTypeDefBaseType().getResolvableStatus() == INTRA_FILE_RESOLVED) {
                return INTRA_FILE_RESOLVED;
            }
            setEffectiveBuiltInType(((YangDerivedInfo<?>) baseType.getDataTypeExtendedInfo())
                    .getEffectiveBuiltInType());
            YangDerivedInfo refDerivedInfo = ((YangDerivedInfo<?>) baseType.getDataTypeExtendedInfo());
            /*
             * Check whether the effective built-in type can have range
             * restrictions, if yes call resolution of range.
             */
            if (isOfRangeRestrictedType(getEffectiveBuiltInType())) {
                if (refDerivedInfo.getResolvedExtendedInfo() == null) {
                    resolveRangeRestriction(null);
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                } else {
                    if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangRangeRestriction)) {
                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                "type.");
                    }
                    resolveRangeRestriction((YangRangeRestriction) refDerivedInfo.getResolvedExtendedInfo());
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                }
                /*
                 * If the effective built-in type is of type string calls
                 * for string resolution.
                 */
            } else if (getEffectiveBuiltInType() == STRING) {
                if (refDerivedInfo.getResolvedExtendedInfo() == null) {
                    resolveStringRestriction(null);
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                } else {
                    if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangStringRestriction)) {
                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                "type.");
                    }
                    resolveStringRestriction((YangStringRestriction) refDerivedInfo.getResolvedExtendedInfo());
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                }
            } else if (getEffectiveBuiltInType() == BINARY) {
                if (refDerivedInfo.getResolvedExtendedInfo() == null) {
                    resolveLengthRestriction(null);
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve length restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                } else {
                    if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangRangeRestriction)) {
                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                "type.");
                    }
                    resolveLengthRestriction((YangRangeRestriction) refDerivedInfo.getResolvedExtendedInfo());
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve length restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                }
            }
        } else {
            setEffectiveBuiltInType((baseType.getDataType()));
            /*
             * Check whether the effective built-in type can have range
             * restrictions, if yes call resolution of range.
             */
            if (isOfRangeRestrictedType(getEffectiveBuiltInType())) {
                if (baseType.getDataTypeExtendedInfo() == null) {
                    resolveRangeRestriction(null);
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                } else {
                    if (!(baseType.getDataTypeExtendedInfo() instanceof YangRangeRestriction)) {
                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                "type.");
                    }
                    resolveRangeRestriction((YangRangeRestriction) baseType.getDataTypeExtendedInfo());
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                }
                /*
                 * If the effective built-in type is of type string calls
                 * for string resolution.
                 */
            } else if (getEffectiveBuiltInType() == STRING) {
                if (baseType.getDataTypeExtendedInfo() == null) {
                    resolveStringRestriction(null);
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                } else {
                    if (!(baseType.getDataTypeExtendedInfo() instanceof YangStringRestriction)) {
                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                "type.");
                    }
                    resolveStringRestriction((YangStringRestriction) baseType.getDataTypeExtendedInfo());
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                }
            } else if (getEffectiveBuiltInType() == BINARY) {
                if (baseType.getDataTypeExtendedInfo() == null) {
                    resolveLengthRestriction(null);
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve length restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                } else {
                    if (!(baseType.getDataTypeExtendedInfo() instanceof YangRangeRestriction)) {
                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                "type.");
                    }
                    resolveLengthRestriction((YangRangeRestriction) baseType.getDataTypeExtendedInfo());
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve length restriction will throw exception
                     * in previous function.
                     */
                    return RESOLVED;
                }
            }
        }

        /*
         * Check if the data type is the one which can't be restricted, in
         * this case check whether no self restrictions should be present.
         */
        if (isOfValidNonRestrictedType(getEffectiveBuiltInType())) {
            if (Strings.isNullOrEmpty(getLengthRestrictionString())
                    && Strings.isNullOrEmpty(getRangeRestrictionString())
                    && getPatternRestriction() == null) {
                return RESOLVED;
            } else {
                throw new DataModelException("YANG file error: Restrictions can't be applied to a given type");
            }
        }

        // Throw exception for unsupported types
        throw new DataModelException("Linker error: Unable to process the derived type.");
    }

    /**
     * Resolves the string restrictions.
     *
     * @param refStringRestriction referred string restriction of typedef
     * @throws DataModelException a violation in data model rule
     */
    private void resolveStringRestriction(YangStringRestriction refStringRestriction) throws DataModelException {
        YangStringRestriction curStringRestriction = null;
        YangRangeRestriction refRangeRestriction = null;
        YangPatternRestriction refPatternRestriction = null;

        /*
         * Check that range restriction should be null when built-in type is
         * string.
         */
        if (!(Strings.isNullOrEmpty(getRangeRestrictionString()))) {
            DataModelException dataModelException = new DataModelException("YANG file error: Range restriction " +
                    "should't be present for string data type.");
            dataModelException.setLine(lineNumber);
            dataModelException.setCharPosition(charPositionInLine);
            throw dataModelException;
        }

        /*
         * If referred restriction and self restriction both are null, no
         * resolution is required.
         */
        if (refStringRestriction == null && Strings.isNullOrEmpty(getLengthRestrictionString())
                && getPatternRestriction() == null) {
            return;
        }

        /*
         * If referred string restriction is not null, take value of length
         * and pattern restriction and assign.
         */
        if (refStringRestriction != null) {
            refRangeRestriction = refStringRestriction.getLengthRestriction();
            refPatternRestriction = refStringRestriction.getPatternRestriction();
        }

        YangRangeRestriction lengthRestriction = resolveLengthRestriction(refRangeRestriction);
        YangPatternRestriction patternRestriction = resolvePatternRestriction(refPatternRestriction);

        /*
         * Check if either of length or pattern restriction is present, if yes
         * create string restriction and assign value.
         */
        if (lengthRestriction != null || patternRestriction != null) {
            curStringRestriction = new YangStringRestriction();
            curStringRestriction.setLengthRestriction(lengthRestriction);
            curStringRestriction.setPatternRestriction(patternRestriction);
        }
        setResolvedExtendedInfo((T) curStringRestriction);
    }

    /**
     * Resolves pattern restriction.
     *
     * @param refPatternRestriction referred pattern restriction of typedef
     * @return resolved pattern restriction
     */
    private YangPatternRestriction resolvePatternRestriction(YangPatternRestriction refPatternRestriction) {
        /*
         * If referred restriction and self restriction both are null, no
         * resolution is required.
         */
        if (refPatternRestriction == null && getPatternRestriction() == null) {
            return null;
        }

        /*
         * If self restriction is null, and referred restriction is present
         * shallow copy the referred to self.
         */
        if (getPatternRestriction() == null) {
            return refPatternRestriction;
        }

        /*
         * If referred restriction is null, and self restriction is present
         * carry out self resolution.
         */
        if (refPatternRestriction == null) {
            return getPatternRestriction();
        }

        /*
         * Get patterns of referred type and add it to current pattern
         * restrictions.
         */
        for (String pattern : refPatternRestriction.getPatternList()) {
            getPatternRestriction().addPattern(pattern);
        }
        return getPatternRestriction();
    }

    /**
     * Resolves the length restrictions.
     *
     * @param refLengthRestriction referred length restriction of typedef
     * @return resolved length restriction
     * @throws DataModelException a violation in data model rule
     */
    private YangRangeRestriction resolveLengthRestriction(YangRangeRestriction refLengthRestriction) throws
            DataModelException {

        /*
         * If referred restriction and self restriction both are null, no
         * resolution is required.
         */
        if (refLengthRestriction == null && Strings.isNullOrEmpty(getLengthRestrictionString())) {
            return null;
        }

        /*
         * If self restriction is null, and referred restriction is present
         * shallow copy the referred to self.
         */
        if (Strings.isNullOrEmpty(getLengthRestrictionString())) {
            return refLengthRestriction;
        }

        /*
         * If referred restriction is null, and self restriction is present
         * carry out self resolution.
         */
        if (refLengthRestriction == null) {
            YangRangeRestriction curLengthRestriction = processLengthRestriction(null, lineNumber,
                    charPositionInLine, false, getLengthRestrictionString());
            return curLengthRestriction;
        }

        /*
         * Carry out self resolution based with obtained effective built-in
         * type and MIN/MAX values as per the referred typedef's values.
         */
        YangRangeRestriction curLengthRestriction = processLengthRestriction(refLengthRestriction, lineNumber,
                charPositionInLine, true, getLengthRestrictionString());

        // Resolve the range with referred typedef's restriction.
        resolveLengthAndRangeRestriction(refLengthRestriction, curLengthRestriction);
        return curLengthRestriction;
    }

    /**
     * Resolves the length/range self and referred restriction, to check whether
     * the all the range interval in self restriction is stricter than the
     * referred typedef's restriction.
     *
     * @param refRestriction referred restriction
     * @param curRestriction self restriction
     */
    private void resolveLengthAndRangeRestriction(YangRangeRestriction refRestriction,
                                                  YangRangeRestriction curRestriction) throws DataModelException {
        for (Object curInterval : curRestriction.getAscendingRangeIntervals()) {
            if (!(curInterval instanceof YangRangeInterval)) {
                throw new DataModelException("Linker error: Current range intervals not processed correctly.");
            }
            try {
                refRestriction.isValidInterval((YangRangeInterval) curInterval);
            } catch (DataModelException e) {
                DataModelException dataModelException = new DataModelException(e);
                dataModelException.setLine(lineNumber);
                dataModelException.setCharPosition(charPositionInLine);
                throw dataModelException;
            }
        }
    }

    /**
     * Resolves the range restrictions.
     *
     * @param refRangeRestriction referred range restriction of typedef
     * @throws DataModelException a violation in data model rule
     */
    private void resolveRangeRestriction(YangRangeRestriction refRangeRestriction) throws DataModelException {

        /*
         * Check that string restriction should be null when built-in type is
         * of range type.
         */
        if (!(Strings.isNullOrEmpty(getLengthRestrictionString())) || getPatternRestriction() != null) {
            DataModelException dataModelException = new DataModelException("YANG file error: Length/Pattern " +
                    "restriction should't be present for int/uint/decimal data type.");
            dataModelException.setLine(lineNumber);
            dataModelException.setCharPosition(charPositionInLine);
            throw dataModelException;
        }

        /*
         * If referred restriction and self restriction both are null, no
         * resolution is required.
         */
        if (refRangeRestriction == null && Strings.isNullOrEmpty(getRangeRestrictionString())) {
            return;
        }

        /*
         * If self restriction is null, and referred restriction is present
         * shallow copy the referred to self.
         */
        if (Strings.isNullOrEmpty(getRangeRestrictionString())) {
            setResolvedExtendedInfo((T) refRangeRestriction);
            return;
        }

        /*
         * If referred restriction is null, and self restriction is present
         * carry out self resolution.
         */
        if (refRangeRestriction == null) {
            YangRangeRestriction curRangeRestriction = processRangeRestriction(null, lineNumber,
                    charPositionInLine, false, getRangeRestrictionString(), getEffectiveBuiltInType());
            setResolvedExtendedInfo((T) curRangeRestriction);
            return;
        }

        /*
         * Carry out self resolution based with obtained effective built-in
         * type and MIN/MAX values as per the referred typedef's values.
         */
        YangRangeRestriction curRangeRestriction = processRangeRestriction(refRangeRestriction, lineNumber,
                charPositionInLine, true, getRangeRestrictionString(), getEffectiveBuiltInType());

        // Resolve the range with referred typedef's restriction.
        resolveLengthAndRangeRestriction(refRangeRestriction, curRangeRestriction);
        setResolvedExtendedInfo((T) curRangeRestriction);
    }

    /**
     * Returns whether the data type is of non restricted type.
     *
     * @param dataType data type to be checked
     * @return true, if data type can't be restricted, false otherwise
     */
    private boolean isOfValidNonRestrictedType(YangDataTypes dataType) {
        return (dataType == BOOLEAN
                || dataType == ENUMERATION
                || dataType == BITS
                || dataType == EMPTY
                || dataType == UNION
                || dataType == IDENTITYREF
                || dataType == LEAFREF);
    }
}
