/*
 * 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.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
     * @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);
    }
}
