/*
 * Copyright 2016 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;
        }
    }
}
