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

import java.util.regex.Pattern;
import org.onosproject.yangutils.datamodel.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangRangeInterval;
import org.onosproject.yangutils.datamodel.YangRangeRestriction;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.utils.YangConstructType;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangBuiltInDataTypeInfo;

import static org.onosproject.yangutils.datamodel.YangDataTypes.DECIMAL64;
import static org.onosproject.yangutils.datamodel.YangDataTypes.INT16;
import static org.onosproject.yangutils.datamodel.YangDataTypes.INT32;
import static org.onosproject.yangutils.datamodel.YangDataTypes.INT64;
import static org.onosproject.yangutils.datamodel.YangDataTypes.INT8;
import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT16;
import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT32;
import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT64;
import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT8;
import static org.onosproject.yangutils.utils.UtilConstants.ADD;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.YangConstructType.LENGTH_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.RANGE_DATA;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.BuiltInTypeObjectFactory.getDataObjectFromString;

/**
 * Represents restriction resolver which provide common utility used by parser
 * and during linking for restriction resolution.
 */
public final class RestrictionResolver {

    private static final String PIPE = "|";
    private static final String INTERVAL = "..";
    private static final int MAX_RANGE_BOUNDARY = 2;
    private static final int MIN_RANGE_BOUNDARY = 1;
    private static final String MIN_KEYWORD = "min";
    private static final String MAX_KEYWORD = "max";

    /**
     * Creates a restriction resolver.
     */
    private RestrictionResolver() {
    }

    /**
     * Processes the range restriction for parser and linker.
     *
     * @param refRangeRestriction    range restriction of referred typedef
     * @param lineNumber             error line number
     * @param charPositionInLine     error character position in line
     * @param hasReferredRestriction whether has referred restriction
     * @param curRangeString         caller type's range string
     * @param effectiveType          effective type, when called from linker
     * @return YANG range restriction
     * @throws DataModelException a violation in data model rule
     */
    public static YangRangeRestriction processRangeRestriction(YangRangeRestriction refRangeRestriction,
                                                               int lineNumber, int charPositionInLine,
                                                               boolean hasReferredRestriction,
                                                               String curRangeString, YangDataTypes effectiveType)
            throws DataModelException {
        YangBuiltInDataTypeInfo<?> startValue;
        YangBuiltInDataTypeInfo<?> endValue;
        YangRangeRestriction rangeRestriction = new YangRangeRestriction();

        String rangeArgument = removeQuotesAndHandleConcat(curRangeString);
        String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));

        for (String rangePart : rangeArguments) {
            String startInterval;
            String endInterval;
            YangRangeInterval rangeInterval = new YangRangeInterval();
            String[] rangeBoundary = rangePart.trim().split(Pattern.quote(INTERVAL));

            if (rangeBoundary.length > MAX_RANGE_BOUNDARY) {
                DataModelException dataModelException = new DataModelException("YANG file error : " +
                        YangConstructType.getYangConstructType(RANGE_DATA) + " " + rangeArgument +
                        " is not valid.");
                dataModelException.setLine(lineNumber);
                dataModelException.setCharPosition(charPositionInLine);
                throw dataModelException;
            }

            if (rangeBoundary.length == MIN_RANGE_BOUNDARY) {
                startInterval = rangeBoundary[0].trim();
                endInterval = rangeBoundary[0].trim();
            } else {
                startInterval = rangeBoundary[0].trim();
                endInterval = rangeBoundary[1].trim();
            }

            try {
                if (hasReferredRestriction && startInterval.equals(MIN_KEYWORD)
                        && refRangeRestriction.getMinRestrictedvalue() != null) {
                    startValue = refRangeRestriction.getMinRestrictedvalue();
                } else if (hasReferredRestriction && startInterval.equals(MAX_KEYWORD)
                        && refRangeRestriction.getMaxRestrictedvalue() != null) {
                    startValue = refRangeRestriction.getMaxRestrictedvalue();
                } else {
                    startValue = getDataObjectFromString(startInterval, effectiveType);
                }
                if (hasReferredRestriction && endInterval.equals(MIN_KEYWORD)
                        && refRangeRestriction.getMinRestrictedvalue() != null) {
                    endValue = refRangeRestriction.getMinRestrictedvalue();
                } else if (hasReferredRestriction && endInterval.equals(MAX_KEYWORD)
                        && refRangeRestriction.getMaxRestrictedvalue() != null) {
                    endValue = refRangeRestriction.getMaxRestrictedvalue();
                } else {
                    endValue = getDataObjectFromString(endInterval, effectiveType);
                }
            } catch (Exception e) {
                DataModelException dataModelException = new DataModelException(e.getMessage());
                dataModelException.setLine(lineNumber);
                dataModelException.setCharPosition(charPositionInLine);
                throw dataModelException;
            }

            rangeInterval.setStartValue(startValue);
            rangeInterval.setEndValue(endValue);

            try {
                rangeRestriction.addRangeRestrictionInterval(rangeInterval);
            } catch (DataModelException dataModelException) {
                dataModelException.setLine(lineNumber);
                dataModelException.setCharPosition(charPositionInLine);
                throw dataModelException;
            }
        }
        return rangeRestriction;
    }

    /**
     * Processes the length restriction for parser and linker.
     *
     * @param refLengthRestriction   length restriction of referred typedef
     * @param lineNumber             error line number
     * @param charPositionInLine     error character position in line
     * @param hasReferredRestriction whether has referred restriction
     * @param curLengthString        caller type's length string
     * @return YANG range restriction
     * @throws DataModelException a violation in data model rule
     */
    public static YangRangeRestriction processLengthRestriction(YangRangeRestriction refLengthRestriction,
                                                                int lineNumber, int charPositionInLine,
                                                                boolean hasReferredRestriction,
                                                                String curLengthString) throws DataModelException {

        YangBuiltInDataTypeInfo<?> startValue;
        YangBuiltInDataTypeInfo<?> endValue;
        YangRangeRestriction lengthRestriction = new YangRangeRestriction<>();

        String rangeArgument = removeQuotesAndHandleConcat(curLengthString);
        String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));

        for (String rangePart : rangeArguments) {
            String startInterval;
            String endInterval;
            YangRangeInterval rangeInterval = new YangRangeInterval<>();
            String[] rangeBoundary = rangePart.trim().split(Pattern.quote(INTERVAL));

            if (rangeBoundary.length > MAX_RANGE_BOUNDARY) {
                DataModelException dataModelException = new DataModelException("YANG file error : " +
                        YangConstructType.getYangConstructType(LENGTH_DATA) + " " + rangeArgument +
                        " is not valid.");
                dataModelException.setLine(lineNumber);
                dataModelException.setCharPosition(charPositionInLine);
                throw dataModelException;
            }

            if (rangeBoundary.length == MIN_RANGE_BOUNDARY) {
                startInterval = rangeBoundary[0].trim();
                endInterval = rangeBoundary[0].trim();
            } else {
                startInterval = rangeBoundary[0].trim();
                endInterval = rangeBoundary[1].trim();
            }

            try {
                if (hasReferredRestriction && startInterval.equals(MIN_KEYWORD)
                        && refLengthRestriction.getMinRestrictedvalue() != null) {
                    startValue = refLengthRestriction.getMinRestrictedvalue();
                } else if (hasReferredRestriction && startInterval.equals(MAX_KEYWORD)
                        && refLengthRestriction.getMaxRestrictedvalue() != null) {
                    startValue = refLengthRestriction.getMaxRestrictedvalue();
                } else {
                    startValue = getDataObjectFromString(startInterval, YangDataTypes.UINT64);
                }
                if (hasReferredRestriction && endInterval.equals(MIN_KEYWORD)
                        && refLengthRestriction.getMinRestrictedvalue() != null) {
                    endValue = refLengthRestriction.getMinRestrictedvalue();
                } else if (hasReferredRestriction && endInterval.equals(MAX_KEYWORD)
                        && refLengthRestriction.getMaxRestrictedvalue() != null) {
                    endValue = refLengthRestriction.getMaxRestrictedvalue();
                } else {
                    endValue = getDataObjectFromString(endInterval, YangDataTypes.UINT64);
                }
            } catch (Exception e) {
                DataModelException dataModelException = new DataModelException(e.getMessage());
                dataModelException.setLine(lineNumber);
                dataModelException.setCharPosition(charPositionInLine);
                throw dataModelException;
            }

            rangeInterval.setStartValue(startValue);
            rangeInterval.setEndValue(endValue);

            try {
                lengthRestriction.addRangeRestrictionInterval(rangeInterval);
            } catch (DataModelException dataModelException) {
                dataModelException.setLine(lineNumber);
                dataModelException.setCharPosition(charPositionInLine);
                throw dataModelException;
            }
        }
        return lengthRestriction;
    }

    /**
     * Returns whether the data type is of range restricted type.
     *
     * @param dataType data type to be checked
     * @return true, if data type can have range restrictions, false otherwise
     */
    public static boolean isOfRangeRestrictedType(YangDataTypes dataType) {
        return (dataType == INT8
                || dataType == INT16
                || dataType == INT32
                || dataType == INT64
                || dataType == UINT8
                || dataType == UINT16
                || dataType == UINT32
                || dataType == UINT64
                || dataType == DECIMAL64);
    }

    /**
     * Removes doubles quotes and concatenates if string has plus symbol.
     *
     * @param yangStringData string from yang file
     * @return concatenated string after removing double quotes
     */
    private static String removeQuotesAndHandleConcat(String yangStringData) {

        yangStringData = yangStringData.replace("\"", EMPTY_STRING);
        String[] tmpData = yangStringData.split(Pattern.quote(ADD));
        StringBuilder builder = new StringBuilder();
        for (String yangString : tmpData) {
            builder.append(yangString);
        }
        return builder.toString();
    }
}
