/*
 * 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.parser.impl.parserutils;

import org.antlr.v4.runtime.ParserRuleContext;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import org.onosproject.yangutils.utils.YangConstructType;
import static org.onosproject.yangutils.utils.YangConstructType.getYangConstructType;

import java.util.Iterator;
import java.util.List;

/**
 * It's a utility to carry out listener validation.
 */
public final class ListenerValidation {

    /**
     * Creates a new listener validation.
     */
    private ListenerValidation() {
    }

    /**
     * Checks parsed data stack is not empty.
     *
     * @param listener Listener's object
     * @param errorType error type needs to be set in error message
     * @param yangConstructType type of parsable data in which error occurred
     * @param parsableDataTypeName name of parsable data type in which error
     *            occurred
     * @param errorLocation location where error occurred
     */
    public static void checkStackIsNotEmpty(TreeWalkListener listener, ListenerErrorType errorType,
            YangConstructType yangConstructType, String parsableDataTypeName,
            ListenerErrorLocation errorLocation) {
        if (listener.getParsedDataStack().empty()) {
            /*
             * If stack is empty it indicates error condition, value of
             * parsableDataTypeName will be null in case there is no name
             * attached to parsable data type.
             */
            String message = constructListenerErrorMessage(errorType, yangConstructType, parsableDataTypeName,
                    errorLocation);
            throw new ParserException(message);
        }
    }

    /**
     * Checks parsed data stack is empty.
     *
     * @param listener Listener's object
     * @param errorType error type needs to be set in error message
     * @param yangConstructType type of parsable data in which error occurred
     * @param parsableDataTypeName name of parsable data type in which error
     *            occurred
     * @param errorLocation location where error occurred
     */
    public static void checkStackIsEmpty(TreeWalkListener listener, ListenerErrorType errorType,
            YangConstructType yangConstructType, String parsableDataTypeName,
            ListenerErrorLocation errorLocation) {

        if (!listener.getParsedDataStack().empty()) {
            /*
             * If stack is empty it indicates error condition, value of
             * parsableDataTypeName will be null in case there is no name
             * attached to parsable data type.
             */
            String message = constructListenerErrorMessage(errorType, yangConstructType, parsableDataTypeName,
                    errorLocation);
            throw new ParserException(message);
        }
    }

    /**
     * Returns parent node config value, if top node does not specify a config
     * statement then default value true is returned.
     *
     * @param listener listener's object
     * @return true/false parent's config value
     */
    public static boolean getParentNodeConfig(TreeWalkListener listener) {
        YangNode parentNode;
        Parsable curData = listener.getParsedDataStack().peek();
        if (curData instanceof YangNode) {
            parentNode = ((YangNode) curData).getParent();
            if (parentNode instanceof YangContainer) {
                return ((YangContainer) parentNode).isConfig();
            } else if (parentNode instanceof YangList) {
                return ((YangList) parentNode).isConfig();
            }
        }
        return true;
    }

    /**
     * Checks if a rule occurrences is as per the expected YANG grammar's
     * cardinality.
     *
     * @param childContext child's context
     * @param yangChildConstruct child construct for whom cardinality is to be
     *            validated
     * @param yangParentConstruct parent construct
     * @param parentName parent name
     * @throws ParserException exception if cardinality check fails
     */
    public static void validateCardinalityMaxOne(List<?> childContext, YangConstructType yangChildConstruct,
                                                 YangConstructType yangParentConstruct, String parentName)
            throws ParserException {

        if (!childContext.isEmpty() && childContext.size() != 1) {
            ParserException parserException = new ParserException("YANG file error: \""
                    + getYangConstructType(yangChildConstruct) + "\" is defined more than once in \""
                    + getYangConstructType(yangParentConstruct) + " " + parentName + "\".");

            Iterator<?> context = childContext.iterator();
            parserException.setLine(((ParserRuleContext) context.next()).getStart().getLine());
            parserException.setCharPosition(((ParserRuleContext) context.next()).getStart().getCharPositionInLine());
            throw parserException;
        }
    }

    /**
     * Checks if a rule occurrences is exactly 1.
     *
     * @param childContext child's context
     * @param yangChildConstruct child construct for whom cardinality is to be
     *                           validated
     * @param yangParentConstruct parent construct
     * @param parentName parent name
     * @param parentContext parents's context
     * @throws ParserException exception if cardinality check fails
     */
    public static void validateCardinalityEqualsOne(List<?> childContext, YangConstructType yangChildConstruct,
                                                    YangConstructType yangParentConstruct, String parentName,
                                                    ParserRuleContext parentContext)
            throws ParserException {

        if (childContext.isEmpty()) {
            ParserException parserException = new ParserException("YANG file error: Missing \""
                    + getYangConstructType(yangChildConstruct) + "\" in \"" + getYangConstructType(yangParentConstruct)
                    + " " + parentName + "\".");
            parserException.setLine(parentContext.getStart().getLine());
            parserException.setCharPosition(parentContext.getStart().getCharPositionInLine());
            throw parserException;
        } else if (!childContext.isEmpty() && childContext.size() != 1) {
            Iterator<?> childcontext = childContext.iterator();
            ParserException parserException = new ParserException("YANG file error: \""
                    + getYangConstructType(yangChildConstruct) + "\" is present more than once in \""
                    + getYangConstructType(yangParentConstruct) + " " + parentName + "\".");
            parserException.setLine(((ParserRuleContext) childcontext.next()).getStart().getLine());
            parserException.setCharPosition(((ParserRuleContext) childcontext.next()).getStart()
                    .getCharPositionInLine());
            throw parserException;
        }
    }

    /**
     * Checks if a rule occurrences is minimum 1.
     *
     * @param childContext child's context
     * @param yangChildConstruct child construct for whom cardinality is to be
     *                           validated
     * @param yangParentConstruct parent construct
     * @param parentName parent name
     * @param parentContext parents's context
     * @throws ParserException exception if cardinality check fails
     */
    public static void validateCardinalityNonZero(List<?> childContext, YangConstructType yangChildConstruct,
                                                  YangConstructType yangParentConstruct, String parentName,
                                                  ParserRuleContext parentContext)
            throws ParserException {

        if (childContext.isEmpty()) {
            ParserException parserException = new ParserException("YANG file error: Missing \""
                    + getYangConstructType(yangChildConstruct) + "\" in \"" + getYangConstructType(yangParentConstruct)
                    + " " + parentName + "\".");

            parserException.setLine(parentContext.getStart().getLine());
            parserException.setCharPosition(parentContext.getStart().getCharPositionInLine());
            throw parserException;
        }
    }

    /**
     * Checks if a either of one construct occurrence.
     *
     * @param child1Context first optional child's context
     * @param yangChild1Construct first child construct for whom cardinality is
     *                            to be validated
     * @param child2Context second optional child's context
     * @param yangChild2Construct second child construct for whom cardinality is
     *                            to be validated
     * @param yangParentConstruct parent construct
     * @param parentName parent name
     * @throws ParserException exception if cardinality check fails
     */
    public static void validateMutuallyExclusiveChilds(List<?> child1Context, YangConstructType yangChild1Construct,
                                                       List<?> child2Context, YangConstructType yangChild2Construct,
                                                       YangConstructType yangParentConstruct, String parentName)
            throws ParserException {

        if (!child1Context.isEmpty() && !child2Context.isEmpty()) {
            ParserException parserException = new ParserException("YANG file error: \""
                    + getYangConstructType(yangChild1Construct) + "\" & \"" + getYangConstructType(yangChild2Construct)
                    + "\" should be mutually exclusive in \"" + getYangConstructType(yangParentConstruct) + " "
                    + parentName + "\".");

            parserException.setLine(((ParserRuleContext) child2Context).getStart().getLine());
            parserException.setCharPosition(((ParserRuleContext) child2Context).getStart().getCharPositionInLine());
            throw parserException;
        }
    }
}
