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

import org.onosproject.yangutils.datamodel.YangAugment;
import org.onosproject.yangutils.datamodel.YangAugmentableNode;
import org.onosproject.yangutils.datamodel.YangInput;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangRpc;
import org.onosproject.yangutils.datamodel.YangSchemaNode;
import org.onosproject.yms.app.utils.TraversalType;
import org.onosproject.yms.app.yab.exceptions.YabException;
import org.onosproject.yms.app.ydt.DefaultYdtAppContext;
import org.onosproject.yms.app.ydt.YangRequestWorkBench;
import org.onosproject.yms.app.ydt.YangResponseWorkBench;
import org.onosproject.yms.app.ydt.YdtAppContext;
import org.onosproject.yms.app.ydt.YdtExtendedContext;
import org.onosproject.yms.app.ydt.YdtMultiInstanceNode;
import org.onosproject.yms.app.ydt.YdtNode;
import org.onosproject.yms.app.yob.DefaultYobBuilder;
import org.onosproject.yms.app.ysr.YangSchemaRegistry;
import org.onosproject.yms.app.ytb.DefaultYangTreeBuilder;
import org.onosproject.yms.ydt.YdtBuilder;
import org.onosproject.yms.ydt.YdtContext;
import org.onosproject.yms.ydt.YdtResponse;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.yms.app.utils.TraversalType.CHILD;
import static org.onosproject.yms.app.utils.TraversalType.PARENT;
import static org.onosproject.yms.app.utils.TraversalType.ROOT;
import static org.onosproject.yms.app.utils.TraversalType.SIBLING;
import static org.onosproject.yms.app.ydt.AppNodeFactory.getAppContext;
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.ydt.YdtContextOperationType.DELETE;
import static org.onosproject.yms.ydt.YmsOperationExecutionStatus.EXECUTION_SUCCESS;

/**
 * Represents YANG application broker. It acts as a broker between Protocol and
 * YANG based application.
 */
public class YangApplicationBroker {

    private static final String GET = "get";
    private static final String SET = "set";
    private static final String AUGMENTED = "Augmented";
    private static final String VOID = "void";
    private final YangSchemaRegistry schemaRegistry;
    private Set<String> augGenMethodSet;

    /**
     * Creates a new YANG application broker.
     *
     * @param schemaRegistry YANG schema registry
     */
    public YangApplicationBroker(YangSchemaRegistry schemaRegistry) {
        this.schemaRegistry = schemaRegistry;
    }

    /**
     * Processes query request of a NBI protocol.
     *
     * @param ydtWorkBench YANG request work bench
     * @return YANG response data tree node context
     * @throws YabException violation in execution of YAB
     */
    public YdtResponse processQuery(YdtBuilder ydtWorkBench)
            throws YabException {
        List<Object> responseObjects = new LinkedList<>();
        YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
        augGenMethodSet = ((YangRequestWorkBench) ydtWorkBench).getAugGenMethodSet();

        for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
             appContext != null; appContext = appContext.getNextSibling()) {
            Object responseObject = processQueryOfApplication(appContext);
            if (responseObject != null) {
                responseObjects.add(responseObject);
            }
        }

        YdtContext rootYdtContext = workBench.getRootNode();
        YdtBuilder responseYdt = buildResponseYdt(responseObjects,
                                                  rootYdtContext.getName(),
                                                  rootYdtContext.getNamespace());

        return new YangResponseWorkBench(responseYdt.getRootNode(),
                                         EXECUTION_SUCCESS,
                                         ydtWorkBench.getYmsOperationType());
    }

    /**
     * Processes edit request of a NBI protocol.
     *
     * @param ydtWorkBench YANG request work bench
     * @return YANG response data tree node context
     * @throws YabException               violation in execution of YAB
     * @throws CloneNotSupportedException clone is not supported
     */
    public YdtResponse processEdit(YdtBuilder ydtWorkBench)
            throws CloneNotSupportedException, YabException {
        YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
        augGenMethodSet = ((YangRequestWorkBench) ydtWorkBench).getAugGenMethodSet();
        for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
             appContext != null; appContext = appContext.getNextSibling()) {
            processEditOfApplication(appContext);
        }

        /*
         * Since for set operation return type is void, there will not be
         * response ydt tree so returning null.
         */
        return new YangResponseWorkBench(null, EXECUTION_SUCCESS,
                                         workBench.getYmsOperationType());
    }

    /**
     * Processes operation request of a NBI protocol.
     *
     * @param ydtWorkBench YANG request work bench
     * @return YANG response data tree node context
     * @throws YabException violation in execution of YAB
     */
    public YdtResponse processOperation(YdtBuilder ydtWorkBench)
            throws YabException {
        YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
        YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
        YdtContext ydtNode = appContext.getModuleContext();
        while (ydtNode != null) {
            YdtContext childYdtNode = ydtNode.getFirstChild();
            YangSchemaNode yangNode = ((YdtNode) childYdtNode).getYangSchemaNode();
            if (yangNode instanceof YangRpc) {
                return processRpcOperationOfApplication(childYdtNode,
                                                        appContext, yangNode,
                                                        workBench);
            }
            ydtNode = ydtNode.getNextSibling();
        }
        return new YangResponseWorkBench(null, EXECUTION_SUCCESS,
                                         ydtWorkBench.getYmsOperationType());
    }

    /**
     * Processes rpc request of an application.
     *
     * @param appContext application context
     * @return response object from application
     */
    private YdtResponse processRpcOperationOfApplication(YdtContext rpcYdt,
                                                         YdtAppContext appContext,
                                                         YangSchemaNode yangRpc,
                                                         YangRequestWorkBench workBench)
            throws YabException {
        Object inputObject = null;
        YdtContext inputYdtNode = getInputYdtNode(rpcYdt);
        if (inputYdtNode != null) {
            inputObject = getYangObject(inputYdtNode);
        }

        Object appObject = getApplicationObjectForRpc(appContext);

        String methodName = yangRpc.getJavaClassNameOrBuiltInType();
        Object outputObject = invokeRpcApplicationsMethod(appObject,
                                                          inputObject,
                                                          methodName);

        String returnType = getReturnTypeOfRpcResponse(appObject,
                                                       inputObject, yangRpc);

        if (!returnType.equals(VOID)) {
            YdtBuilder responseYdt = buildRpcResponseYdt(outputObject,
                                                         workBench);
            return new YangResponseWorkBench(responseYdt.getRootNode(),
                                             EXECUTION_SUCCESS,
                                             workBench.getYmsOperationType());
        }

        return new YangResponseWorkBench(null, EXECUTION_SUCCESS,
                                         workBench.getYmsOperationType());
    }

    /**
     * Processes query request of an application.
     *
     * @param appContext application context
     * @return response object from application
     */
    private Object processQueryOfApplication(YdtAppContext appContext)
            throws YabException {
        YdtContext ydtNode = appContext.getModuleContext();

        // Update application context tree if any node is augmented
        YangNode yangNode = (YangNode) appContext.getYangSchemaNode();
        if (yangNode.isDescendantNodeAugmented()) {
            processAugmentForChildNode(appContext, yangNode);
        }

        String appName = getCapitalCase(((YdtNode) appContext.getModuleContext())
                                                .getYangSchemaNode()
                                                .getJavaClassNameOrBuiltInType());

        // get YangObject of YdtContext from YOB
        Object outputObject = getYangObject(ydtNode);

        TraversalType curTraversal = ROOT;
        do {
            if (curTraversal != PARENT) {

                // find application and get application's object using YSR
                Object appManagerObject = getApplicationObject(appContext);

                // find which method to invoke
                String methodName = getApplicationMethodName(appContext,
                                                             appName, GET);

                String moduleName = appContext.getAppData()
                        .getRootSchemaNode().getName();

                // invoke application's getter method
                outputObject = invokeApplicationsMethod(appManagerObject,
                                                        outputObject,
                                                        methodName, moduleName);
            }

            /*
             * AppContext may contain other nodes if it is augmented, so
             * traverse the appContext tree
             */
            if (curTraversal != PARENT && appContext.getFirstChild() != null) {
                curTraversal = CHILD;
                appContext = appContext.getFirstChild();
            } else if (appContext.getNextSibling() != null) {
                curTraversal = SIBLING;
                appContext = appContext.getNextSibling();
            } else {
                curTraversal = PARENT;
                if (appContext.getParent().getParent() != null) {
                    appContext = appContext.getParent();
                }
            }
            // no need to do any operation for logical root node
        } while (appContext.getParent().getParent() != null);
        return outputObject;
    }

    /**
     * Processes edit request of an application.
     *
     * @param appContext application context
     * @throws YabException               violation in execution of YAB
     * @throws CloneNotSupportedException clone is not supported
     */
    private void processEditOfApplication(YdtAppContext appContext)
            throws CloneNotSupportedException, YabException {

        // process delete request if operation type is delete and both
        if (appContext.getOperationType() != OTHER_EDIT) {
            processDeleteRequestOfApplication(appContext);
        }

        // process edit request if operation type is other edit and both
        if (appContext.getOperationType() != DELETE_ONLY) {
            YdtContext ydtNode = appContext.getModuleContext();

            String appName = getCapitalCase(((YdtNode) appContext.getModuleContext())
                                                    .getYangSchemaNode()
                                                    .getJavaClassNameOrBuiltInType());

            // get YO from YOB
            Object outputObject = getYangObject(ydtNode);

            TraversalType curTraversal = ROOT;
            do {
                if (curTraversal != PARENT) {

                    // find application and get application's object using YSR
                    Object appManagerObject = getApplicationObject(appContext);

                    // find which method to invoke
                    String methodName = getApplicationMethodName(appContext,
                                                                 appName, SET);

                    String moduleName = appContext.getAppData()
                            .getRootSchemaNode().getName();

                    // invoke application's setter method
                    invokeApplicationsMethod(appManagerObject, outputObject,
                                             methodName, moduleName);
                }

                /*
                 * AppContext may contain other nodes if it is augmented,
                 * so traverse the appContext tree
                 */
                if (curTraversal != PARENT && appContext.getFirstChild() != null) {
                    curTraversal = CHILD;
                    appContext = appContext.getFirstChild();
                } else if (appContext.getNextSibling() != null) {
                    curTraversal = SIBLING;
                    appContext = appContext.getNextSibling();
                } else {
                    curTraversal = PARENT;
                    if (appContext.getParent().getParent() != null) {
                        appContext = appContext.getParent();
                    }
                }
                // no need to do any operation for logical root node
            } while (appContext.getParent().getParent() != null);
        }
    }

    /**
     * Processes delete request of an application.
     *
     * @param appContext application context
     * @throws YabException               violation in execution of YAB
     * @throws CloneNotSupportedException clone is not supported
     */
    private void processDeleteRequestOfApplication(YdtAppContext appContext)
            throws CloneNotSupportedException, YabException {
        TraversalType curTraversal = ROOT;
        List<YdtContext> deleteNodes = appContext.getDeleteNodes();

        if (deleteNodes != null && !deleteNodes.isEmpty()) {

            /*
             * Split the current Ydt tree into two trees.
             * Delete Tree with all nodes with delete operation and other
             * tree with other edit operation
             */
            YdtContext deleteTree = buildDeleteTree(deleteNodes);

            /*
             * If any of nodes in ydt delete tree is augmented then add
             * augmented nodes to current ydt tree
             */
            processAugmentedNodesForDelete(deleteTree.getFirstChild(), appContext);

            Object inputObject = getYangObject(deleteTree.getFirstChild());

            String appName = getCapitalCase(((YdtNode) appContext.getModuleContext())
                                                    .getYangSchemaNode()
                                                    .getJavaClassNameOrBuiltInType());

            do {
                if (curTraversal == ROOT || curTraversal == SIBLING) {
                    while (appContext.getLastChild() != null) {
                        appContext = appContext.getLastChild();
                    }
                }

                // getAugmentApplication manager object
                Object appManagerObject = getApplicationObject(appContext);

                // find which method to invoke
                String methodName = getApplicationMethodName(appContext,
                                                             appName, SET);

                String moduleName = appContext.getAppData().getRootSchemaNode()
                        .getName();

                // invoke application's setter method
                invokeApplicationsMethod(appManagerObject, inputObject,
                                         methodName, moduleName);

                if (appContext.getPreviousSibling() != null) {
                    curTraversal = SIBLING;
                    appContext = appContext.getPreviousSibling();
                } else if (appContext.getParent() != null) {
                    curTraversal = PARENT;
                    appContext = appContext.getParent();
                }
            } while (appContext.getParent() != null);
        }
    }

    /**
     * Traverses data model tree and if any node is augmented, then
     * adds child to current application context.
     *
     * @param curAppContext current application context
     * @param schemaNode    YANG data model node, either module or augment
     */
    protected void processAugmentForChildNode(YdtAppContext curAppContext,
                                              YangNode schemaNode) {
        YangNode yangNode = schemaNode.getChild();
        if (yangNode == null) {
            return;
        }

        TraversalType curTraversal = CHILD;
        while (!yangNode.equals(schemaNode)) {
            if (curTraversal != PARENT && yangNode instanceof YangAugmentableNode
                    && !((YangAugmentableNode) yangNode).getAugmentedInfoList()
                    .isEmpty()) {
                updateAppTreeWithAugmentNodes(yangNode, curAppContext);
            }

            if (curTraversal != PARENT && yangNode.getChild() != null
                    && yangNode.isDescendantNodeAugmented()) {
                curTraversal = CHILD;
                yangNode = yangNode.getChild();
            } else if (yangNode.getNextSibling() != null) {
                curTraversal = SIBLING;
                yangNode = yangNode.getNextSibling();
            } else {
                curTraversal = PARENT;
                yangNode = yangNode.getParent();
            }
        }
    }

    /**
     * Traverses YDT delete tree and if any YDT node is augmented then
     * updates the YDT delete tree with augment nodes.
     *
     * @param deleteTree YDT delete tree
     * @param appContext application context
     */
    protected void processAugmentedNodesForDelete(YdtContext deleteTree,
                                                  YdtAppContext appContext) {
        TraversalType curTraversal = ROOT;
        YdtContext ydtContext = deleteTree.getFirstChild();

        if (ydtContext == null) {
            /*
             * Delete request is for module, so check all the nodes under
             * module whether it is augmented.
             */
            YangNode yangNode = ((YangNode) ((YdtNode) deleteTree)
                    .getYangSchemaNode());
            if (yangNode.isDescendantNodeAugmented()) {
                processAugmentForChildNode(appContext, yangNode);
            }
            return;
        }

        while (!ydtContext.equals(deleteTree)) {
            if (curTraversal != PARENT && ((YdtNode) ydtContext)
                    .getYdtContextOperationType() == DELETE) {
                YangNode yangNode = ((YangNode) ((YdtNode) ydtContext)
                        .getYangSchemaNode());
                if (yangNode instanceof YangAugmentableNode) {
                    updateAppTreeWithAugmentNodes(yangNode, appContext);
                }
                if (yangNode.isDescendantNodeAugmented()) {
                    processAugmentForChildNode(appContext, yangNode);
                }
            }

            if (curTraversal != PARENT && ydtContext.getFirstChild() != null) {
                curTraversal = CHILD;
                ydtContext = ydtContext.getFirstChild();
            } else if (ydtContext.getNextSibling() != null) {
                curTraversal = SIBLING;
                ydtContext = ydtContext.getNextSibling();
            } else {
                curTraversal = PARENT;
                ydtContext = ydtContext.getParent();
            }
        }
    }

    /**
     * Returns response YANG data tree using YTB.
     *
     * @param responseObjects list of application's response objects
     * @param name            application YANG name
     * @param namespace       application YANG namespace
     * @return response YANG data tree
     */
    private YdtBuilder buildResponseYdt(List<Object> responseObjects,
                                        String name, String namespace) {
        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
        return treeBuilder.getYdtBuilderForYo(responseObjects,
                                              name, namespace, null, schemaRegistry);
    }

    private YdtBuilder buildRpcResponseYdt(Object responseObject,
                                           YangRequestWorkBench requestWorkBench) {
        DefaultYangTreeBuilder treeBuilder = new DefaultYangTreeBuilder();
        return treeBuilder.getYdtForRpcResponse(responseObject, requestWorkBench);
    }

    /**
     * Builds delete tree for list of delete nodes.
     *
     * @param deleteNodes list of delete nodes
     * @return deleteTree YANG data tree for delete operation
     * @throws CloneNotSupportedException clone is not supported
     */
    protected YdtContext buildDeleteTree(List<YdtContext> deleteNodes) throws
            CloneNotSupportedException {
        Iterator<YdtContext> iterator = deleteNodes.iterator();
        YdtContext deleteTree = null;
        while (iterator.hasNext()) {
            YdtContext deleteNode = iterator.next();
            if (((YdtExtendedContext) deleteNode.getParent())
                    .getYdtContextOperationType() != DELETE) {
                cloneAncestorsOfDeleteNode(deleteNode);
                deleteTree = unlinkDeleteNodeFromCurrentTree((YdtNode) deleteNode);
            }
        }

        if (deleteTree != null) {
            while (deleteTree.getParent() != null) {
                deleteTree = deleteTree.getParent();
            }
        }
        return deleteTree;
    }

    /**
     * Clones ancestor nodes of delete node.
     *
     * @param deleteNode node to be deleted
     * @throws CloneNotSupportedException clone not supported
     */
    private void cloneAncestorsOfDeleteNode(YdtContext deleteNode)
            throws CloneNotSupportedException {
        YdtNode clonedNode;
        YdtNode previousNode = null;

        // Clone the parents of delete node to form delete tree
        YdtNode nodeToClone = (YdtNode) deleteNode.getParent();
        while (nodeToClone != null) {
            // If node is not cloned yet
            if (nodeToClone.getClonedNode() == null) {
                clonedNode = nodeToClone.clone();
                unlinkCurrentYdtNode(clonedNode);
                if (nodeToClone instanceof YdtMultiInstanceNode) {
                    addKeyLeavesToClonedNode(nodeToClone, clonedNode);
                }
                nodeToClone.setClonedNode(clonedNode);
            } else {
                // already node is cloned
                clonedNode = (YdtNode) nodeToClone.getClonedNode();
            }

            if (previousNode != null) {
                /*
                 * add previous cloned node as child of current cloned node
                 * so that tree will be formed from delete node parent to
                 * logical root node.
                 */
                clonedNode.addChild(previousNode, false);
            }
            previousNode = clonedNode;
            nodeToClone = nodeToClone.getParent();
        }
    }

    /**
     * Unlinks delete node from current YANG data tree of application
     * and links it to cloned delete tree.
     *
     * @param deleteNode node to be unlinked
     * @return deleteNode delete node linked to cloned delete tree
     */
    private YdtNode unlinkDeleteNodeFromCurrentTree(YdtNode deleteNode) {
        YdtNode parentClonedNode = (YdtNode) deleteNode.getParent().getClonedNode();
        unlinkNodeFromParent(deleteNode);
        unlinkNodeFromSibling(deleteNode);

        /*
         * Set all the pointers of node to null before adding as child
         * to parent's cloned node.
         */
        deleteNode.setParent(null);
        deleteNode.setPreviousSibling(null);
        deleteNode.setNextSibling(null);

        parentClonedNode.addChild(deleteNode, false);
        return deleteNode;
    }

    /**
     * Adds key leaf nodes to cloned YDT node from current Ydt node.
     *
     * @param curNode    current YDT node
     * @param clonedNode cloned YDT node
     */
    private void addKeyLeavesToClonedNode(YdtNode curNode, YdtNode clonedNode)
            throws CloneNotSupportedException {
        YdtNode keyClonedLeaf;
        List<YdtContext> keyList = ((YdtMultiInstanceNode) curNode)
                .getKeyNodeList();
        if (keyList != null && !keyList.isEmpty()) {
            for (YdtContext keyLeaf : keyList) {
                keyClonedLeaf = ((YdtNode) keyLeaf).clone();
                unlinkCurrentYdtNode(keyClonedLeaf);
                clonedNode.addChild(keyClonedLeaf, true);
            }
        }
    }

    /**
     * Updates application context tree if any of the nodes in current
     * application context tree is augmented.
     *
     * @param yangNode      YANG schema node which is augmented
     * @param curAppContext current application context tree
     */
    private void updateAppTreeWithAugmentNodes(YangNode yangNode,
                                               YdtAppContext curAppContext) {
        YdtAppContext childAppContext;
        for (YangAugment yangAugment : ((YangAugmentableNode) yangNode)
                .getAugmentedInfoList()) {
            Object appManagerObject = schemaRegistry
                    .getRegisteredApplication(yangAugment.getParent());
            if (appManagerObject != null
                    && augGenMethodSet.add(yangAugment.getSetterMethodName())) {
                childAppContext = addChildToYdtAppTree(curAppContext,
                                                       yangAugment);
                processAugmentForChildNode(childAppContext, yangAugment);
            }
        }
    }

    /**
     * Adds child node to current application context tree.
     *
     * @param curAppContext current application context
     * @param augment       augment data model node
     * @return childAppContext child node added
     */
    private YdtAppContext addChildToYdtAppTree(YdtAppContext curAppContext,
                                               YangNode augment) {
        DefaultYdtAppContext childAppContext = getAppContext(true);
        childAppContext.setParent(curAppContext);
        childAppContext.setOperationType(curAppContext.getOperationType());
        childAppContext.setAugmentingSchemaNode(augment);
        curAppContext.addChild(childAppContext);
        return childAppContext;
    }

    /**
     * Unlinks the current node from its parent.
     *
     * @param deleteNode node which should be unlinked from YDT tree
     */
    private void unlinkNodeFromParent(YdtNode deleteNode) {
        YdtNode parentNode = deleteNode.getParent();
        if (parentNode.getFirstChild().equals(deleteNode)
                && parentNode.getLastChild().equals(deleteNode)) {
            parentNode.setChild(null);
            parentNode.setLastChild(null);
        } else if (parentNode.getFirstChild().equals(deleteNode)) {
            parentNode.setChild(deleteNode.getNextSibling());
        } else if (parentNode.getLastChild().equals(deleteNode)) {
            parentNode.setLastChild(deleteNode.getPreviousSibling());
        }
    }

    /**
     * Unlinks the current node from its sibling.
     *
     * @param deleteNode node which should be unlinked from YDT tree
     */
    private void unlinkNodeFromSibling(YdtNode deleteNode) {
        YdtNode previousSibling = deleteNode.getPreviousSibling();
        YdtNode nextSibling = deleteNode.getNextSibling();
        if (nextSibling != null && previousSibling != null) {
            previousSibling.setNextSibling(nextSibling);
            nextSibling.setPreviousSibling(previousSibling);
        } else if (nextSibling != null) {
            nextSibling.setPreviousSibling(null);
        } else if (previousSibling != null) {
            previousSibling.setNextSibling(null);
        }
    }

    /**
     * Unlinks current Ydt node from parent, sibling and child.
     *
     * @param ydtNode YANG data tree node
     */
    private void unlinkCurrentYdtNode(YdtNode ydtNode) {
        ydtNode.setParent(null);
        ydtNode.setNextSibling(null);
        ydtNode.setPreviousSibling(null);
        ydtNode.setChild(null);
        ydtNode.setLastChild(null);
    }

    /**
     * Returns YANG object for YDT node.
     *
     * @param ydtNode YANG data node
     * @return YANG object for YDT node
     */
    private Object getYangObject(YdtContext ydtNode) {
        checkNotNull(ydtNode);
        DefaultYobBuilder yobBuilder = new DefaultYobBuilder();
        return yobBuilder.getYangObject((YdtExtendedContext) ydtNode,
                                        schemaRegistry);
    }

    /**
     * Returns application manager object for YDT node.
     *
     * @param appContext YDT application context
     * @return application manager object
     */
    private Object getApplicationObjectForRpc(YdtAppContext appContext) {
        checkNotNull(appContext);
        while (appContext.getFirstChild() != null) {
            appContext = appContext.getFirstChild();
        }
        return schemaRegistry.getRegisteredApplication(appContext.getAppData()
                                                               .getRootSchemaNode());
    }

    /**
     * Returns application manager object of application.
     *
     * @param appContext application context
     * @return application manager object
     */
    private Object getApplicationObject(YdtAppContext appContext) {
        return schemaRegistry.getRegisteredApplication(appContext.getAppData()
                                                               .getRootSchemaNode());
    }

    /**
     * Converts name to capital case.
     *
     * @param yangIdentifier identifier
     * @return name to capital case
     */
    private String getCapitalCase(String yangIdentifier) {
        return yangIdentifier.substring(0, 1).toUpperCase() +
                yangIdentifier.substring(1);
    }

    /**
     * Returns get/set method name for application's request.
     *
     * @param appContext application context
     * @return get/set method name for application's query request
     */
    private String getApplicationMethodName(YdtAppContext appContext,
                                            String appName,
                                            String operation) {
        if (appContext.getYangSchemaNode() instanceof YangModule) {
            return operation + appName;
        }

        String augment = ((YangAugment) appContext
                .getAugmentingSchemaNode()).getTargetNode().get(0)
                .getResolvedNode().getJavaClassNameOrBuiltInType();
        return new StringBuilder().append(operation).append(AUGMENTED)
                .append(appName).append(getCapitalCase(augment)).toString();
    }

    /**
     * Returns rpc's input schema node.
     *
     * @param rpcNode rpc schema node
     * @return rpc's input YDT node
     */
    private YdtContext getInputYdtNode(YdtContext rpcNode) {
        YdtContext inputNode = rpcNode.getFirstChild();
        while (inputNode != null) {
            YangSchemaNode yangInputNode = ((YdtNode) inputNode)
                    .getYangSchemaNode();
            if (yangInputNode instanceof YangInput) {
                return inputNode;
            }
            inputNode = rpcNode.getNextSibling();
        }
        return null;
    }

    /**
     * Invokes application method for RPC request.
     *
     * @param appManagerObject application manager object
     * @param inputObject      input parameter object of method
     * @param methodName       method name which should be invoked
     * @return response object from application
     * @throws YabException violation in execution of YAB
     */
    private Object invokeApplicationsMethod(Object appManagerObject,
                                            Object inputObject,
                                            String methodName, String appName)
            throws YabException {
        checkNotNull(appManagerObject);
        Class<?> appClass = appManagerObject.getClass();
        try {
            Method methodObject = appClass.getDeclaredMethod(methodName,
                                                             inputObject.getClass());
            if (methodObject != null) {
                return methodObject.invoke(appManagerObject, inputObject);
            }
            throw new YabException("No such method in application");
        } catch (IllegalAccessException | NoSuchMethodException e) {
            throw new YabException(e);
        } catch (InvocationTargetException e) {
            throw new YabException("Invocation exception in service " + appName,
                                   e.getCause());
        }
    }

    /**
     * Invokes application method for RPC request.
     *
     * @param appObject   application manager object
     * @param inputObject input parameter object of method
     * @param yangNode    method name which should be invoked
     * @return response object from application
     * @throws YabException violation in execution of YAB
     */
    private String getReturnTypeOfRpcResponse(Object appObject,
                                              Object inputObject, YangSchemaNode
                                                      yangNode) throws YabException {
        Method methodObject = null;
        try {
            if (inputObject == null) {
                methodObject = appObject.getClass()
                        .getDeclaredMethod(yangNode.getJavaClassNameOrBuiltInType(),
                                           null);
            } else {
                methodObject = appObject.getClass()
                        .getDeclaredMethod(yangNode.getJavaClassNameOrBuiltInType(),
                                           inputObject.getClass().getInterfaces());
            }
            if (methodObject != null) {
                return methodObject.getReturnType().getSimpleName();
            }
            throw new YabException("No such method in application");
        } catch (NoSuchMethodException e) {
            throw new YabException(e);
        }
    }

    /**
     * Invokes application method for RPC request.
     *
     * @param appManagerObject application manager object
     * @param inputParamObject input parameter object of method
     * @param methodName       method name which should be invoked
     * @return response object from application
     * @throws YabException violation in execution of YAB
     */
    private Object invokeRpcApplicationsMethod(Object appManagerObject,
                                               Object inputParamObject,
                                               String methodName) throws YabException {
        checkNotNull(appManagerObject);
        Class<?> appClass = appManagerObject.getClass();
        try {
            Method methodObject;
            if (inputParamObject == null) {
                methodObject = appClass.getDeclaredMethod(methodName, null);
                if (methodObject != null) {
                    return methodObject.invoke(appManagerObject);
                }
            } else {
                methodObject = appClass.getDeclaredMethod(methodName,
                                                          inputParamObject
                                                                  .getClass()
                                                                  .getInterfaces());
                if (methodObject != null) {
                    return methodObject.invoke(appManagerObject, inputParamObject);
                }
            }
            throw new YabException("No such method in application");
        } catch (IllegalAccessException | NoSuchMethodException |
                InvocationTargetException e) {
            throw new YabException(e);
        }
    }

    /**
     * Sets the augment setter method name.
     *
     * @param augGenMethodSet augment setter method name
     */
    public void setAugGenMethodSet(Set<String> augGenMethodSet) {
        this.augGenMethodSet = augGenMethodSet;
    }
}
