/*
 * 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 java.util.LinkedList;
import java.util.List;

import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.utils.builtindatatype.YangBuiltInDataTypeInfo;

import static org.onosproject.yangutils.utils.builtindatatype.BuiltInTypeObjectFactory.getDataObjectFromString;
import static com.google.common.base.Preconditions.checkNotNull;

/*-
 * Reference RFC 6020.
 *
 * The range Statement
 *
 *  The "range" statement, which is an optional sub-statement to the
 *  "type" statement, takes as an argument a range expression string.  It
 *  is used to restrict integer and decimal built-in types, or types
 *  derived from those.
 *
 *  A range consists of an explicit value, or a lower-inclusive bound,
 *  two consecutive dots "..", and an upper-inclusive bound.  Multiple
 *  values or ranges can be given, separated by "|".  If multiple values
 *  or ranges are given, they all MUST be disjoint and MUST be in
 *  ascending order.  If a range restriction is applied to an already
 *  range-restricted type, the new restriction MUST be equal or more
 *  limiting, that is raising the lower bounds, reducing the upper
 *  bounds, removing explicit values or ranges, or splitting ranges into
 *  multiple ranges with intermediate gaps.  Each explicit value and
 *  range boundary value given in the range expression MUST match the
 *  type being restricted, or be one of the special values "min" or
 *  "max". "min" and "max" mean the minimum and maximum value accepted
 *  for the type being restricted, respectively.
 */

/**
 * Represents ascending range restriction information.
 *
 * @param <T> range type (data type)
 */
public class YangRangeRestriction<T extends YangBuiltInDataTypeInfo<T>>
        implements YangDesc, YangReference, YangAppErrorInfo {

    /**
     * Ascending list of range interval restriction. If the restriction is a
     * single value, the start and end length of the range is same.
     */
    private List<YangRangeInterval<T>> ascendingRangeIntervals;

    /**
     * Textual reference.
     */
    private String reference;

    /**
     * Application's error message, to be used for data error.
     */
    private String errorMessage;

    /**
     * Application's error tag, to be filled in data validation error response.
     */
    private String errorAppTag;

    /**
     * Textual description.
     */
    private String description;

    /**
     * Creates YANG range restriction object.
     */
    public YangRangeRestriction() {
    }

    /**
     * Returns the list of range interval restriction in ascending order.
     *
     * @return list of range interval restriction in ascending order
     */
    public List<YangRangeInterval<T>> getAscendingRangeIntervals() {
        return ascendingRangeIntervals;
    }

    /**
     * Sets the list of range interval restriction in ascending order.
     *
     * @param rangeList list of range interval restriction in ascending order
     */
    private void setAscendingRangeIntervals(List<YangRangeInterval<T>> rangeList) {
        ascendingRangeIntervals = rangeList;
    }

    /**
     * Returns the minimum valid value as per the restriction.
     *
     * @throws DataModelException data model exception for minimum restriction
     * @return minimum restricted value
     */
    public T getMinRestrictedvalue() throws DataModelException {
        if (getAscendingRangeIntervals() == null) {
            throw new DataModelException("No range restriction info");
        }
        if (getAscendingRangeIntervals().isEmpty()) {
            throw new DataModelException("No range interval info");
        }
        return getAscendingRangeIntervals().get(0).getStartValue();
    }

    /**
     * Returns the maximum valid value as per the restriction.
     *
     * @throws DataModelException data model exception for maximum restriction
     * @return minimum maximum value
     */
    public T getMaxRestrictedvalue() throws DataModelException {
        if (getAscendingRangeIntervals() == null) {
            throw new DataModelException("No range restriction info");
        }
        if (getAscendingRangeIntervals().isEmpty()) {
            throw new DataModelException("No range interval info");
        }
        return getAscendingRangeIntervals()
                .get(getAscendingRangeIntervals().size() - 1).getEndValue();
    }

    /**
     * Adds new interval to extend its range in the last. i.e. newly added
     * interval needs to be bigger than the biggest interval in the list.
     *
     * @param newInterval restricted length interval
     * @throws DataModelException data model exception for range restriction
     */
    public void addRangeRestrictionInterval(YangRangeInterval<T> newInterval) throws DataModelException {

        checkNotNull(newInterval);
        checkNotNull(newInterval.getStartValue());

        if (getAscendingRangeIntervals() == null) {
            /*
             * First interval that is being added, and it must be the smallest
             * interval.
             */
            setAscendingRangeIntervals(new LinkedList<YangRangeInterval<T>>());
            getAscendingRangeIntervals().add(newInterval);
            return;
        }

        T curMaxvalue = getMaxRestrictedvalue();

        if (newInterval.getStartValue().compareTo(curMaxvalue) != 1) {
            throw new DataModelException(
                    "New added range interval is lesser than the old interval(s)");
        }

        getAscendingRangeIntervals()
                .add(getAscendingRangeIntervals().size(), newInterval);
    }

    /**
     * Check if the given value is correct as per the restriction.
     *
     * @param valueInString value
     * @return true, if the value is confirming to restriction, false otherwise
     * @throws DataModelException data model error
     */
    public boolean isValidValueString(String valueInString) throws DataModelException {

        if (getAscendingRangeIntervals() == null
                || getAscendingRangeIntervals().isEmpty()) {
            // Throw exception, At least one default range needs to be set in constructor or in linker.
            throw new DataModelException("Range interval missing in range restriction.");

        }

        YangDataTypes type = getAscendingRangeIntervals().get(0).getStartValue().getYangType();
        YangBuiltInDataTypeInfo<?> value = getDataObjectFromString(valueInString, type);

        for (YangRangeInterval<T> interval : getAscendingRangeIntervals()) {
            int rangeStartCompareRes = interval.getStartValue().compareTo((T) value);
            int rangeEndCompareRes = interval.getEndValue().compareTo((T) value);

            if (rangeStartCompareRes <= 0 && rangeEndCompareRes >= 0) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns the textual reference of the length restriction.
     *
     * @return textual reference of the length restriction
     */
    @Override
    public String getReference() {
        return reference;
    }

    /**
     * Sets the textual reference of the length restriction.
     *
     * @param ref textual reference of the length restriction
     */
    @Override
    public void setReference(String ref) {
        reference = ref;
    }

    /**
     * Returns the description of the length restriction.
     *
     * @return description of the length restriction
     */
    @Override
    public String getDescription() {
        return description;
    }

    /**
     * Sets the description of the length restriction.
     *
     * @param desc description of the length restriction
     */
    @Override
    public void setDescription(String desc) {
        description = desc;

    }

    /**
     * Returns application's error message, to be used for data error.
     *
     * @return Application's error message, to be used for data error
     */
    @Override
    public String getGetErrorMessage() {
        return errorMessage;
    }

    /**
     * Sets Application's error message, to be used for data error.
     *
     * @param errMsg Application's error message, to be used for data error
     */
    @Override
    public void setErrorMessage(String errMsg) {
        errorMessage = errMsg;

    }

    /**
     * Returns application's error tag, to be used for data error.
     *
     * @return application's error tag, to be used for data error
     */
    @Override
    public String getGetErrorAppTag() {
        return errorAppTag;
    }

    /**
     * Sets application's error tag, to be used for data error.
     *
     * @param errTag application's error tag, to be used for data error.
     */
    @Override
    public void setErrorAppTag(String errTag) {
        errorAppTag = errTag;
    }
}
