/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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.yms.app.ydt;

import org.onosproject.yangutils.datamodel.YangAugment;
import org.onosproject.yangutils.datamodel.YangSchemaNode;
import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yms.app.ydt.exceptions.YdtException;
import org.onosproject.yms.ydt.YdtContextOperationType;

import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.DELETE_ONLY;
import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.OTHER_EDIT;
import static org.onosproject.yms.app.ydt.YdtConstants.errorMsg;
import static org.onosproject.yms.ydt.YdtContextOperationType.CREATE;
import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
import static org.onosproject.yms.ydt.YdtContextOperationType.MERGE;

/**
 * Utils to support yang data tree node creation.
 */
final class YdtUtils {

    // YDT formatted error string
    private static final String E_CREATE_OP =
            "Create request is not allowed under delete operation.";
    private static final String E_DELETE_OP =
            "Delete request is not allowed under create operation.";
    private static final String FMT_TOO_FEW =
            "Too few key parameters in %s. Expected %d; actual %d.";
    private static final String FMT_TOO_MANY =
            "Too many key parameters in %s. Expected %d; actual %d.";

    //No instantiation.
    private YdtUtils() {
    }

    /**
     * Returns the app tree operation type with the help of YdtOperation type.
     *
     * @param opType ydt operation type
     * @return app tree operation type
     */
    static YdtAppNodeOperationType getAppOpTypeFromYdtOpType(
            YdtContextOperationType opType) {
        // Get the app tree operation type.
        switch (opType) {
            case CREATE:
            case MERGE:
            case REPLACE:
                return OTHER_EDIT;

            case DELETE:
            case REMOVE:
                return DELETE_ONLY;

            default:
                return null;
            //TODO handle the default data type.
        }
    }

    /**
     * Validates the various combination of operation type.
     *
     * @param parentOpType Reference for parent node operation type
     * @param childOpType  type of YANG data tree node operation
     * @throws YdtException when user requested node operation type is
     *                      not valid as per parent node operation type
     */
    private static void validateOperationType(YdtContextOperationType parentOpType,
                                              YdtContextOperationType childOpType)
            throws YdtException {

        switch (parentOpType) {
            case CREATE:
                // Inside the create operation delete operation should not come.
                if (childOpType == DELETE) {
                    throw new YdtException(E_CREATE_OP);
                }
                break;
            case DELETE:
                // Inside the delete operation create operation should not come.
                if (childOpType == CREATE) {
                    throw new YdtException(E_DELETE_OP);
                }
                break;
            default:
                //TODO check all possible scenario.
        }
    }

    /**
     * Returns the operation type for non leaf node.
     * When "operation" attribute for current node is not specified or null,
     * then the operation applied to the parent data node of the
     * configuration is used. If no parent data node is available,
     * then the default-operation'value is used.
     * If default operation type is not set, merge will be taken as default
     * operation type.
     *
     * @param type    operation type of parent node
     * @param defType YDT default operation type
     * @return operation type for current non leaf node
     */
    private static YdtContextOperationType getOperationType(
            YdtContextOperationType type, YdtContextOperationType defType) {
        return type != null ? type : (defType != null ? defType : MERGE);
    }

    /**
     * Returns the yang node identifier with requested name and namespace.
     *
     * @param name      name of the node
     * @param namespace namespace of the node
     * @return yang node identifier
     */
    static YangSchemaNodeIdentifier getNodeIdentifier(String name,
                                                      String namespace) {
        YangSchemaNodeIdentifier id = new YangSchemaNodeIdentifier();
        id.setName(name);
        id.setNameSpace(new NameSpace(namespace));
        return id;
    }

    /**
     * Checks the user supplied list of argument match's the expected value
     * or not.
     *
     * @param name     name of the parent list/leaf-list node
     * @param expected count suppose to be
     * @param actual   user supplied values count
     * @throws YdtException when user requested multi instance node instance's
     *                      count doesn't fit into the allowed instance limit
     */
    static void checkElementCount(String name, int expected,
                                  int actual) throws YdtException {
        if (expected < actual) {
            throw new YdtException(
                    errorMsg(FMT_TOO_MANY, name, expected, actual));
        } else if (expected > actual) {
            throw new YdtException(
                    errorMsg(FMT_TOO_FEW, name, expected, actual));
        }
    }

    /**
     * Returns the valid operation type for requested ydt node after performing
     * validation.
     *
     * @param opType     user requested operation type
     * @param newNode    new requested ydt node
     * @param parentNode parent node under which new node to be added
     * @param defOpType  YDT context operation type
     * @return operation type
     * @throws YdtException when user requested node operation type is
     *                      not valid as per parent node operation type
     */
    static YdtContextOperationType getValidOpType(
            YdtContextOperationType opType, YdtContextOperationType defOpType,
            YdtNode newNode, YdtNode parentNode)
            throws YdtException {

        switch (newNode.getYdtType()) {

            case SINGLE_INSTANCE_NODE:
            case MULTI_INSTANCE_NODE:

                // Reference for parent node operation type.
                YdtContextOperationType parentOpType =
                        parentNode.getYdtContextOperationType();

                if (opType == null) {
                    opType = getOperationType(parentOpType, defOpType);
                } else if (parentOpType != null) {
                    validateOperationType(parentOpType, opType);
                }

                return opType;

            /*
             * Nodes other then single/multi instance node does not support
             * operation type so no need of validation for those.
             */
            default:
                return null;
        }
    }

    /**
     * Returns augmenting node module yang schema node.
     *
     * @param id          schema node identifier
     * @param contextInfo Yang Schema node context info
     *                    which is having YangSchemaNode and
     *                    ContextSwitchedNode
     * @return augmenting node module yang schema node
     * @throws YdtException when user requested node schema doesn't exist
     */
    public static YangSchemaNode getAugmentingSchemaNode(
            YangSchemaNodeIdentifier id,
            YangSchemaNodeContextInfo contextInfo) throws YdtException {
        YangSchemaNode lastAugMod = null;
        YangSchemaNode switchedNode =
                contextInfo.getContextSwitchedNode();

        // Finding the last augmenting schema for case/choice scenario.
        while (switchedNode != null) {
            if (switchedNode instanceof YangAugment) {
                lastAugMod = switchedNode;
            }
            try {
                switchedNode = switchedNode.getChildSchema(id)
                        .getContextSwitchedNode();
            } catch (DataModelException e) {
                throw new YdtException(e.getMessage());
            }
        }
        return lastAugMod;
    }

    /**
     * De-reference all the tree node by walking the whole YDT from logical
     * root node.
     * This will be called only when any exception occurs while processing
     * the node in Ydt tree.
     *
     * @param rootNode ydt logical root node
     */
    public static void freeRestResources(YdtNode rootNode) {

        YdtNode currentNode = rootNode;
        while (currentNode != null) {

            // Move down to first child
            YdtNode nextNode = currentNode.getFirstChild();
            if (nextNode != null) {
                currentNode = nextNode;
                continue;
            }

            // No child nodes, so walk tree
            while (currentNode != null) {
                // To keep the track of last sibling.
                YdtNode lastSibling = currentNode;

                // Move to sibling if possible.
                nextNode = currentNode.getNextSibling();

                // free currentNode resources
                free(lastSibling);

                lastSibling.getNamespace();
                if (nextNode != null) {
                    currentNode = nextNode;
                    break;
                }

                // Move up
                if (currentNode.equals(rootNode)) {
                    currentNode = null;
                } else {
                    currentNode = currentNode.getParent();
                    lastSibling.setParent(null);
                }
            }
        }
    }

    /**
     * Free the give YDT node by de-referencing it to null.
     *
     * @param node node to be freed
     */
    private static void free(YdtNode node) {
        if (node.getParent() != null) {
            YdtNode parent = node.getParent();
            parent.setChild(null);
            parent.setLastChild(null);
            if (node.getNextSibling() != null) {
                parent.setChild(node.getNextSibling());
            }
        }
        YdtNode parentRef = node.getParent();
        node = new YdtLogicalNode(null, null);
        node.setParent(parentRef);
    }
}
