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

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

        for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
             appContext != null; appContext = appContext.getNextSibling()) {
            Object responseObject = processQueryOfApplication(appContext);
            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;

        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);

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

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

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

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

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

                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) {
                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) 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 |
                InvocationTargetException e) {
            throw new YabException(e);
        }
    }

    /**
     * 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());
            }
        } catch (NoSuchMethodException e) {
            new YabException(e);
        }
        return methodObject.getReturnType().getSimpleName();
    }

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