/*
 * 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.yangutils.translator.tojava.javamodel;

import java.io.IOException;
import java.util.List;

import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
import org.onosproject.yangutils.datamodel.YangInput;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangLeavesHolder;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangOutput;
import org.onosproject.yangutils.datamodel.YangRpc;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangUses;
import org.onosproject.yangutils.translator.exception.TranslatorException;
import org.onosproject.yangutils.translator.tojava.JavaAttributeInfo;
import org.onosproject.yangutils.translator.tojava.JavaCodeGenerator;
import org.onosproject.yangutils.translator.tojava.JavaFileInfo;
import org.onosproject.yangutils.translator.tojava.JavaFileInfoContainer;
import org.onosproject.yangutils.translator.tojava.JavaQualifiedTypeInfo;
import org.onosproject.yangutils.translator.tojava.TempJavaCodeFragmentFiles;
import org.onosproject.yangutils.translator.tojava.TempJavaCodeFragmentFilesContainer;
import org.onosproject.yangutils.translator.tojava.TempJavaFragmentFiles;
import org.onosproject.yangutils.translator.tojava.utils.YangPluginConfig;

import static org.onosproject.yangutils.translator.tojava.JavaAttributeInfo.getAttributeInfoForTheData;
import static org.onosproject.yangutils.translator.tojava.JavaQualifiedTypeInfo.getQualifiedTypeInfoOfCurNode;
import static org.onosproject.yangutils.translator.tojava.utils.AttributesJavaDataType.getJavaDataType;
import static org.onosproject.yangutils.translator.tojava.utils.AttributesJavaDataType.getJavaImportClass;
import static org.onosproject.yangutils.translator.tojava.utils.AttributesJavaDataType.getJavaImportPackage;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getCamelCase;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getCapitalCase;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getPackageDirPathFromJavaJPackage;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getParentNodeInGenCode;
import static org.onosproject.yangutils.translator.tojava.utils.YangJavaModelUtils.updatePackageInfo;
import static org.onosproject.yangutils.utils.UtilConstants.ACTIVATE;
import static org.onosproject.yangutils.utils.UtilConstants.COMPONENT;
import static org.onosproject.yangutils.utils.UtilConstants.DEACTIVATE;
import static org.onosproject.yangutils.utils.UtilConstants.MANAGER;
import static org.onosproject.yangutils.utils.UtilConstants.REFERENCE;
import static org.onosproject.yangutils.utils.UtilConstants.REFERENCE_CARDINALITY;
import static org.onosproject.yangutils.utils.UtilConstants.SERVICE;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;

/**
 * Represents rpc information extended to support java code generation.
 */
public class YangJavaRpc
        extends YangRpc
        implements JavaCodeGenerator, JavaCodeGeneratorInfo {

    /**
     * Contains the information of the java file being generated.
     */
    private JavaFileInfo javaFileInfo;

    /**
     * Temproary file for code generation.
     */
    private TempJavaCodeFragmentFiles tempJavaCodeFragmentFiles;

    private boolean isInputLeafHolder;
    private boolean isOutputLeafHolder;
    private boolean isInputSingleChildHolder;
    private boolean isOutputSingleChildHolder;

    /**
     * Creates an instance of YANG java rpc.
     */
    public YangJavaRpc() {
        super();
        setJavaFileInfo(new JavaFileInfo());
    }

    /**
     * Returns the generated java file information.
     *
     * @return generated java file information
     */
    @Override
    public JavaFileInfo getJavaFileInfo() {

        if (javaFileInfo == null) {
            throw new TranslatorException("missing java info in java datamodel node");
        }
        return javaFileInfo;
    }

    /**
     * Sets the java file info object.
     *
     * @param javaInfo java file info object
     */
    @Override
    public void setJavaFileInfo(JavaFileInfo javaInfo) {
        javaFileInfo = javaInfo;
    }

    @Override
    public TempJavaCodeFragmentFiles getTempJavaCodeFragmentFiles() {
        return tempJavaCodeFragmentFiles;
    }

    @Override
    public void setTempJavaCodeFragmentFiles(TempJavaCodeFragmentFiles fileHandle) {
        tempJavaCodeFragmentFiles = fileHandle;
    }

    /**
     * Prepares the information for java code generation corresponding to YANG
     * RPC info.
     *
     * @param yangPlugin YANG plugin config
     * @throws TranslatorException translator operations fails
     */
    @Override
    public void generateCodeEntry(YangPluginConfig yangPlugin)
            throws TranslatorException {

        if (!(this instanceof JavaCodeGeneratorInfo)) {
            // TODO:throw exception
        }

        // Add package information for rpc and create corresponding folder.
        try {
            updatePackageInfo(this, yangPlugin);
            if (this.getChild() != null) {
                processNodeEntry(this.getChild(), yangPlugin);
                if (this.getChild().getNextSibling() != null) {
                    processNodeEntry(this.getChild().getNextSibling(), yangPlugin);
                }
            }
        } catch (IOException e) {
            throw new TranslatorException("Failed to prepare generate code entry for RPC node " + this.getName());
        }
    }

    /**
     * Creates a java file using the YANG RPC info.
     *
     * @throws TranslatorException translator operations fails
     */
    @Override
    public void generateCodeExit()
            throws TranslatorException {
        // Get the parent module/sub-module.
        YangNode parent = getParentNodeInGenCode(this);

        // Parent should be holder of rpc or notification.
        if (!(parent instanceof RpcNotificationContainer)) {
            throw new TranslatorException("parent node of rpc can only be module or sub-module");
        }

        /*
         * Create attribute info for input and output of rpc and add it to the
         * parent import list.
         */

        JavaAttributeInfo javaAttributeInfoOfInput = null;
        JavaAttributeInfo javaAttributeInfoOfOutput = null;

        // Get the child input and output node and obtain create java attribute
        // info.
        YangNode yangNode = this.getChild();
        while (yangNode != null) {
            if (yangNode instanceof YangInput) {
                javaAttributeInfoOfInput = processNodeExit(yangNode, getJavaFileInfo().getPluginConfig());

            } else if (yangNode instanceof YangOutput) {
                javaAttributeInfoOfOutput = processNodeExit(yangNode, getJavaFileInfo().getPluginConfig());
            } else {
                // TODO throw exception
            }
            yangNode = yangNode.getNextSibling();
        }

        if (!(parent instanceof TempJavaCodeFragmentFilesContainer)) {
            throw new TranslatorException("missing parent temp file handle");
        }

        /*
         * Add the rpc information to the parent's service temp file.
         */
        try {
            String rpcsChildNodePkg = getPackageDirPathFromJavaJPackage(getJavaFileInfo().getBaseCodeGenPath() +
                    (getJavaFileInfo().getPackage() + "." + getJavaFileInfo().getJavaName()).toLowerCase());

            ((TempJavaCodeFragmentFilesContainer) parent).getTempJavaCodeFragmentFiles().getServiceTempFiles()
                    .addJavaSnippetInfoToApplicableTempFiles(javaAttributeInfoOfInput, javaAttributeInfoOfOutput,
                            ((JavaFileInfoContainer) parent).getJavaFileInfo().getPluginConfig(),
                            ((YangNode) this).getName(), isInputLeafHolder(), isOutputLeafHolder(),
                            isInputSingleChildHolder(), isOutputSingleChildHolder());

            if (javaAttributeInfoOfInput != null && javaAttributeInfoOfOutput != null
                    && isInputLeafHolder() && isOutputLeafHolder()) {
                deleteDirectoryWhenNoFileIsGeneratedForInputOutput(rpcsChildNodePkg);
            } else if (javaAttributeInfoOfInput != null && javaAttributeInfoOfOutput == null
                    && isInputLeafHolder()) {
                deleteDirectoryWhenNoFileIsGeneratedForInputOutput(rpcsChildNodePkg);
            } else if (javaAttributeInfoOfInput == null && javaAttributeInfoOfOutput != null
                    && isOutputLeafHolder()) {
                deleteDirectoryWhenNoFileIsGeneratedForInputOutput(rpcsChildNodePkg);
            } else {
                YangNode node = this.getChild();
                while (node != null) {
                    YangNode tempNode = node.getChild();
                    while (tempNode != null) {
                        if (tempNode instanceof YangUses) {
                            boolean isCodeGenerated = true;
                            if (node instanceof YangJavaInput) {
                                isCodeGenerated = ((YangJavaInput) node).isCodeGenFlag();
                            } else if (node instanceof YangJavaOutput) {
                                isCodeGenerated = ((YangJavaOutput) node).isCodeGenFlag();
                            }
                            if (!isCodeGenerated) {
                                deleteDirectoryWhenNoFileIsGeneratedForInputOutput(rpcsChildNodePkg);
                            }
                        }
                        tempNode = tempNode.getNextSibling();
                    }
                    node = node.getNextSibling();
                }
            }
        } catch (IOException e) {
            throw new TranslatorException("Failed to generate code for RPC node " + this.getName());
        }
        // No file will be generated during RPC exit.
    }

    /**
     * When there is no file generation for input output node we should delete the directory generated
     * for RPC.
     *
     * @param emptyPkg empty package
     * @throws IOException when fails to do IO operations
     */
    private void deleteDirectoryWhenNoFileIsGeneratedForInputOutput(String emptyPkg)
            throws IOException {
        deleteDirectory(emptyPkg);
    }

    /**
     * Creates an attribute info object corresponding to a data model node and
     * return it.
     *
     * @param childNode   child data model node(input / output) for which the java code generation
     *                    is being handled
     * @param currentNode parent node (module / sub-module) in which the child node is an attribute
     * @return AttributeInfo attribute details required to add in temporary
     * files
     */
    public JavaAttributeInfo getChildNodeAsAttributeInParentService(
            YangNode childNode, YangNode currentNode) {

        YangNode parentNode = getParentNodeInGenCode(currentNode);

        String childNodeName = ((JavaFileInfoContainer) childNode).getJavaFileInfo().getJavaName();
        /*
         * Get the import info corresponding to the attribute for import in
         * generated java files or qualified access
         */
        JavaQualifiedTypeInfo qualifiedTypeInfo = getQualifiedTypeInfoOfCurNode(childNode,
                getCapitalCase(childNodeName));
        if (!(parentNode instanceof TempJavaCodeFragmentFilesContainer)) {
            throw new TranslatorException("Parent node does not have file info");
        }

        TempJavaFragmentFiles tempJavaFragmentFiles;
        tempJavaFragmentFiles = ((TempJavaCodeFragmentFilesContainer) parentNode)
                .getTempJavaCodeFragmentFiles()
                .getServiceTempFiles();

        if (tempJavaFragmentFiles == null) {
            throw new TranslatorException("Parent node does not have service file info");
        }
        boolean isQualified = addImportToService(qualifiedTypeInfo);
        return getAttributeInfoForTheData(qualifiedTypeInfo, childNodeName, null, isQualified, false);
    }

    /**
     * Process input/output nodes.
     *
     * @param node             YANG node
     * @param yangPluginConfig plugin configurations
     */
    private void processNodeEntry(YangNode node, YangPluginConfig yangPluginConfig) {
        YangLeavesHolder holder = (YangLeavesHolder) node;
        if (node.getChild() == null) {
            if (holder.getListOfLeaf() != null && holder.getListOfLeafList().isEmpty()
                    && holder.getListOfLeaf().size() == 1) {
                setCodeGenFlagForNode(node, false);
            } else if (holder.getListOfLeaf().isEmpty() && holder.getListOfLeafList() != null
                    && holder.getListOfLeafList().size() == 1) {
                setCodeGenFlagForNode(node, false);
            } else {
                setCodeGenFlagForNode(node, true);
            }
        } else if (node.getChild() != null && holder.getListOfLeaf().isEmpty()
                && holder.getListOfLeafList().isEmpty()) {
            if (getNumberOfChildNodes(node) == 1) {
                if (node.getChild() instanceof YangUses) {
                    setCodeGenFlagForNode(node, getCodeGenFlagWhenUsesIsAChildNode(node));
                } else {
                    setCodeGenFlagForNode(node, false);
                }
            } else {
                setCodeGenFlagForNode(node, true);
            }
        } else {
            setCodeGenFlagForNode(node, true);
        }
    }

    /*Returns code gen flag when uses is a child node.*/
    private boolean getCodeGenFlagWhenUsesIsAChildNode(YangNode node) {
        YangUses uses = (YangUses) node.getChild();

        List<YangNode> groupingChildResolvedNodes = uses.getUsesResolvedNodeList();
        List<List<YangLeaf>> groupingChildResolvedLeaves = uses.getUsesResolvedLeavesList();
        List<List<YangLeafList>> groupingChildResolvedLeafList = uses.getUsesResolvedListOfLeafList();

        if (!groupingChildResolvedNodes.isEmpty()
                && groupingChildResolvedNodes.size() == 1
                && groupingChildResolvedLeaves.isEmpty()
                && groupingChildResolvedLeafList.isEmpty()) {
            return false;
        } else if (groupingChildResolvedNodes.isEmpty()
                && isOnlyOneLeafPresentInGrouping(groupingChildResolvedLeaves)
                && groupingChildResolvedLeafList.isEmpty()) {
            return false;
        } else if (groupingChildResolvedNodes.isEmpty()
                && groupingChildResolvedLeaves.isEmpty()
                && isOnlyOneLeafListPresentInGrouping(groupingChildResolvedLeafList)) {
            return false;
        }
        return (groupingChildResolvedNodes.isEmpty()
                && groupingChildResolvedLeaves.isEmpty()
                && groupingChildResolvedLeafList.isEmpty());
    }

    /**
     * Process input/output nodes.
     *
     * @param node             YANG node
     * @param yangPluginConfig plugin configurations
     * @return java attribute info
     */
    private JavaAttributeInfo processNodeExit(YangNode node, YangPluginConfig yangPluginConfig) {
        YangLeavesHolder holder = (YangLeavesHolder) node;
        if (node.getChild() == null) {
            if (holder.getListOfLeaf() != null && holder.getListOfLeafList().isEmpty()
                    && holder.getListOfLeaf().size() == 1) {
                return processNodeWhenOnlyOneLeafIsPresent(node, yangPluginConfig);

            } else if (holder.getListOfLeaf().isEmpty() && holder.getListOfLeafList() != null
                    && holder.getListOfLeafList().size() == 1) {
                return processNodeWhenOnlyOneLeafListIsPresent(node, yangPluginConfig);
            } else {
                return processNodeWhenMultipleContaintsArePresent(node);
            }
        } else if (node.getChild() != null && holder.getListOfLeaf().isEmpty()
                && holder.getListOfLeafList().isEmpty()) {
            if (getNumberOfChildNodes(node) == 1) {
                return processNodeWhenOnlyOneChildNodeIsPresent(node, yangPluginConfig);
            } else {
                return processNodeWhenMultipleContaintsArePresent(node);
            }
        } else {
            return processNodeWhenMultipleContaintsArePresent(node);
        }
    }

    /**
     * Process input/output node when one leaf is present.
     *
     * @param node             input/output node
     * @param yangPluginConfig plugin configurations
     * @return java attribute for node
     */
    private JavaAttributeInfo processNodeWhenOnlyOneLeafIsPresent(YangNode node,
            YangPluginConfig yangPluginConfig) {

        YangLeavesHolder holder = (YangLeavesHolder) node;
        YangLeaf leaf = holder.getListOfLeaf().get(0);
        setLeafHolderFlag(node, true);
        return getAttributeInfoForLeaf(leaf, yangPluginConfig);
    }

    /**
     * Process input/output node when one leaf list is present.
     *
     * @param node             input/output node
     * @param yangPluginConfig plugin configurations
     * @return java attribute for node
     */
    private JavaAttributeInfo processNodeWhenOnlyOneLeafListIsPresent(YangNode node,
            YangPluginConfig yangPluginConfig) {

        YangLeavesHolder holder = (YangLeavesHolder) node;
        YangLeafList leafList = holder.getListOfLeafList().get(0);
        setLeafHolderFlag(node, true);
        return getAttributeInfoForLeafList(leafList, yangPluginConfig);
    }

    /**
     * Returns java attribute info for leaf.
     *
     * @param leaf             YANG leaf
     * @param yangPluginConfig plugin configurations
     * @return java attribute info for leaf
     */
    private JavaAttributeInfo getAttributeInfoForLeaf(YangLeaf leaf, YangPluginConfig yangPluginConfig) {
        JavaLeafInfoContainer javaLeaf = (JavaLeafInfoContainer) leaf;
        javaLeaf.setConflictResolveConfig(yangPluginConfig.getConflictResolver());
        javaLeaf.updateJavaQualifiedInfo();
        JavaAttributeInfo javaAttributeInfo = getAttributeInfoForTheData(
                javaLeaf.getJavaQualifiedInfo(),
                javaLeaf.getJavaName(yangPluginConfig.getConflictResolver()),
                javaLeaf.getDataType(),
                addTypeImport(javaLeaf.getDataType(), false, yangPluginConfig), false);
        return javaAttributeInfo;
    }

    /**
     * Returns java attribute info for leaf list.
     *
     * @param leafList         YANG leaf list
     * @param yangPluginConfig plugin configurations
     * @return java attribute info for leaf list
     */
    private JavaAttributeInfo getAttributeInfoForLeafList(YangLeafList leafList,
            YangPluginConfig yangPluginConfig) {
        JavaLeafInfoContainer javaLeaf = (JavaLeafInfoContainer) leafList;
        javaLeaf.setConflictResolveConfig(yangPluginConfig.getConflictResolver());
        javaLeaf.updateJavaQualifiedInfo();
        ((TempJavaCodeFragmentFilesContainer) this.getParent()).getTempJavaCodeFragmentFiles()
                .getServiceTempFiles().getJavaImportData().setIfListImported(true);
        JavaAttributeInfo javaAttributeInfo = getAttributeInfoForTheData(
                javaLeaf.getJavaQualifiedInfo(),
                javaLeaf.getJavaName(yangPluginConfig.getConflictResolver()),
                javaLeaf.getDataType(),
                addTypeImport(javaLeaf.getDataType(), true, yangPluginConfig),
                true);
        return javaAttributeInfo;
    }

    /**
     * Process input/output node when one child node is present.
     *
     * @param node             input/output node
     * @param yangPluginConfig plugin configurations
     * @return java attribute for node
     */
    private JavaAttributeInfo processNodeWhenOnlyOneChildNodeIsPresent(YangNode node,
            YangPluginConfig yangPluginConfig) {
        JavaFileInfo rpcInfo = getJavaFileInfo();
        String clsInfo = "";
        JavaQualifiedTypeInfo childInfo = new JavaQualifiedTypeInfo();
        if (node.getChild() instanceof YangJavaUses) {
            YangJavaUses uses = (YangJavaUses) node.getChild();
            return processNodeWhenUsesIsChild(uses, node, yangPluginConfig);
        } else {
            String pkg = (rpcInfo.getPackage() + "." + rpcInfo.getJavaName() + "."
                    + getCamelCase(node.getName(), yangPluginConfig.getConflictResolver())).toLowerCase();
            clsInfo = getCapitalCase(
                    getCamelCase(node.getChild().getName(), yangPluginConfig.getConflictResolver()));
            childInfo.setPkgInfo(pkg);
            childInfo.setClassInfo(clsInfo);
        }
        boolean isList = false;
        if (node.getChild() instanceof YangList) {
            isList = true;
        }
        boolean isQualified = addImportToService(childInfo);

        JavaAttributeInfo javaAttributeInfo =
                getAttributeInfoForTheData(childInfo, clsInfo, null, isQualified, isList);

        setLeafHolderFlag(node, false);
        setSingleChildHolderFlag(node, true);
        return javaAttributeInfo;
    }

    /**
     * Returns java attribute info when child node is uses.
     *
     * @param uses             YANG uses node
     * @param node             YANG node
     * @param yangPluginConfig plugin configurations
     * @return java attribute info when child node is uses
     */
    private JavaAttributeInfo processNodeWhenUsesIsChild(YangUses uses, YangNode node,
            YangPluginConfig yangPluginConfig) {
        String clsInfo = "";
        JavaQualifiedTypeInfo childInfo = new JavaQualifiedTypeInfo();
        List<YangNode> groupingChildResolvedNodes = uses.getUsesResolvedNodeList();
        List<List<YangLeaf>> groupingChildResolvedLeaves = uses.getUsesResolvedLeavesList();
        List<List<YangLeafList>> groupingChildResolvedLeafList = uses.getUsesResolvedListOfLeafList();

        if (!groupingChildResolvedNodes.isEmpty()
                && groupingChildResolvedNodes.size() == 1
                && groupingChildResolvedLeaves.isEmpty()
                && groupingChildResolvedLeafList.isEmpty()) {
            YangNode childNodeOfGrouping = groupingChildResolvedNodes.get(0);
            boolean isList = false;
            if (childNodeOfGrouping instanceof YangList) {
                isList = true;
            }
            JavaFileInfo childNodeOfGroupingInfo =
                    ((JavaFileInfoContainer) childNodeOfGrouping).getJavaFileInfo();
            childInfo.setClassInfo(getCapitalCase(childNodeOfGroupingInfo.getJavaName()));
            childInfo.setPkgInfo(childNodeOfGroupingInfo.getPackage());
            clsInfo = childInfo.getClassInfo();
            boolean isQualified = addImportToService(childInfo);
            setLeafHolderFlag(node, false);
            setSingleChildHolderFlag(node, true);
            return getAttributeInfoForTheData(childInfo, clsInfo, null, isQualified, isList);

        } else if (groupingChildResolvedNodes.isEmpty()
                && isOnlyOneLeafPresentInGrouping(groupingChildResolvedLeaves)
                && groupingChildResolvedLeafList.isEmpty()) {

            YangLeaf leaf = groupingChildResolvedLeaves.get(0).get(0);
            setLeafHolderFlag(node, true);
            return getAttributeInfoForLeaf(leaf, yangPluginConfig);

        } else if (groupingChildResolvedNodes.isEmpty()
                && groupingChildResolvedLeaves.isEmpty()
                && isOnlyOneLeafListPresentInGrouping(groupingChildResolvedLeafList)) {
            YangLeafList leafList = groupingChildResolvedLeafList.get(0).get(0);
            setLeafHolderFlag(node, true);
            return getAttributeInfoForLeafList(leafList, yangPluginConfig);

        } else if (groupingChildResolvedNodes.isEmpty()
                && groupingChildResolvedLeaves.isEmpty()
                && groupingChildResolvedLeafList.isEmpty()) {
            return null;
        } else {
            return processNodeWhenMultipleContaintsArePresent(node);
        }
    }

    /*Return true if only one leaf is present in grouping node.*/
    private boolean isOnlyOneLeafPresentInGrouping(List<List<YangLeaf>> groupingChildResolvedLeaves) {
        if (!groupingChildResolvedLeaves.isEmpty() &&
                groupingChildResolvedLeaves.size() == 1) {
            List<YangLeaf> leaves = groupingChildResolvedLeaves.get(0);
            return leaves.size() == 1;
        } else {
            return false;
        }
    }

    /*Returns true is only one leaf list is present in grouping node.*/
    private boolean isOnlyOneLeafListPresentInGrouping(List<List<YangLeafList>> groupingChildResolvedLeafList) {

        if (!groupingChildResolvedLeafList.isEmpty() &&
                groupingChildResolvedLeafList.size() == 1) {
            List<YangLeafList> leaves = groupingChildResolvedLeafList.get(0);
            return leaves.size() == 1;
        } else {
            return false;
        }
    }

    /**
     * Process input/output node when multiple leaf and child nodes are present.
     *
     * @param node input/output node
     * @return java attribute for node
     */
    private JavaAttributeInfo processNodeWhenMultipleContaintsArePresent(YangNode node) {

        setLeafHolderFlag(node, false);
        setSingleChildHolderFlag(node, false);
        return getChildNodeAsAttributeInParentService(node, this);
    }

    /**
     * Adds type import to the RPC import list.
     *
     * @param type         YANG type
     * @param isList       is list attribute
     * @param pluginConfig plugin configurations
     * @return type import to the RPC import list
     */
    private boolean addTypeImport(YangType<?> type, boolean isList, YangPluginConfig pluginConfig) {

        String classInfo = getJavaImportClass(type, isList, pluginConfig.getConflictResolver());
        if (classInfo == null) {
            classInfo = getJavaDataType(type);
            return false;
        } else {
            classInfo = getJavaImportClass(type, isList, pluginConfig.getConflictResolver());
            String pkgInfo = getJavaImportPackage(type, isList, pluginConfig.getConflictResolver());
            JavaQualifiedTypeInfo importInfo = new JavaQualifiedTypeInfo();
            importInfo.setPkgInfo(pkgInfo);
            importInfo.setClassInfo(classInfo);
            if (!((JavaFileInfoContainer) this.getParent()).getJavaFileInfo().getJavaName().equals(classInfo)) {
                return addImportToService(importInfo);
            } else {
                return true;
            }
        }
    }

    /**
     * Adds to service class import list.
     *
     * @param importInfo import info
     * @return true or false
     */
    private boolean addImportToService(JavaQualifiedTypeInfo importInfo) {
        JavaFileInfo fileInfo = ((JavaFileInfoContainer) this.getParent()).getJavaFileInfo();

        if (importInfo.getClassInfo().contentEquals(SERVICE)
                || importInfo.getClassInfo().contentEquals(COMPONENT)
                || importInfo.getClassInfo().contentEquals(getCapitalCase(ACTIVATE))
                || importInfo.getClassInfo().contentEquals(getCapitalCase(DEACTIVATE))
                || importInfo.getClassInfo().contentEquals(REFERENCE_CARDINALITY)
                || importInfo.getClassInfo().contentEquals(REFERENCE)
                || importInfo.getClassInfo().contentEquals(getCapitalCase(fileInfo.getJavaName() + SERVICE))
                || importInfo.getClassInfo().contentEquals(getCapitalCase(fileInfo.getJavaName() + MANAGER))) {
            return true;
        }

        String className;
        className = getCapitalCase(fileInfo.getJavaName()) + "Service";

        return ((TempJavaCodeFragmentFilesContainer) this.getParent()).getTempJavaCodeFragmentFiles()
                .getServiceTempFiles().getJavaImportData().addImportInfo(importInfo,
                        className, fileInfo.getPackage());

    }

    /**
     * Sets leaf holder flag for input/output.
     *
     * @param node input/output node
     * @param flag true or false
     */
    private void setLeafHolderFlag(YangNode node, boolean flag) {
        if (node instanceof YangJavaInput) {
            setInputLeafHolder(flag);
        } else {
            setOutputLeafHolder(flag);
        }
    }

    /**
     * Sets sing child holder flag for input/output.
     *
     * @param node input/output node
     * @param flag true or false
     */
    private void setSingleChildHolderFlag(YangNode node, boolean flag) {
        if (node instanceof YangJavaInput) {
            setInputSingleChildHolder(flag);
        } else {
            setOutputSingleChildHolder(flag);
        }
    }

    /**
     * Sets code generator flag for input and output.
     *
     * @param node YANG node
     * @param flag cod generator flag
     */
    private void setCodeGenFlagForNode(YangNode node, boolean flag) {
        if (node instanceof YangJavaInput) {
            ((YangJavaInput) node).setCodeGenFlag(flag);
        } else {
            ((YangJavaOutput) node).setCodeGenFlag(flag);
        }

    }

    /**
     * Counts the number of child nodes of a YANG node.
     *
     * @param node YANG node
     * @return count of children
     */
    private int getNumberOfChildNodes(YangNode node) {
        YangNode tempNode = node.getChild();
        int count = 0;
        if (tempNode != null) {
            count = 1;
        }
        while (tempNode != null) {

            tempNode = tempNode.getNextSibling();
            if (tempNode != null) {
                count++;
            }
        }
        return count;
    }

    /**
     * Returns true if input is a leaf holder.
     *
     * @return true if input is a leaf holder
     */
    public boolean isInputLeafHolder() {
        return isInputLeafHolder;
    }

    /**
     * Sets true if input is a leaf holder.
     *
     * @param isInputLeafHolder true if input is a leaf holder
     */
    public void setInputLeafHolder(boolean isInputLeafHolder) {
        this.isInputLeafHolder = isInputLeafHolder;
    }

    /**
     * Returns true if output is a leaf holder.
     *
     * @return true if output is a leaf holder
     */
    public boolean isOutputLeafHolder() {
        return isOutputLeafHolder;
    }

    /**
     * Sets true if output is a leaf holder.
     *
     * @param isOutputLeafHolder true if output is a leaf holder
     */
    public void setOutputLeafHolder(boolean isOutputLeafHolder) {
        this.isOutputLeafHolder = isOutputLeafHolder;
    }

    /**
     * Returns true if input is single child holder.
     *
     * @return true if input is single child holder
     */
    public boolean isInputSingleChildHolder() {
        return isInputSingleChildHolder;
    }

    /**
     * Sets true if input is single child holder.
     *
     * @param isInputSingleChildHolder true if input is single child holder
     */
    public void setInputSingleChildHolder(boolean isInputSingleChildHolder) {
        this.isInputSingleChildHolder = isInputSingleChildHolder;
    }

    /**
     * Returns true if output is single child holder.
     *
     * @return true if output is single child holder
     */
    public boolean isOutputSingleChildHolder() {
        return isOutputSingleChildHolder;
    }

    /**
     * Sets true if output is single child holder.
     *
     * @param isOutputSingleChildHolder true if output is single child holder
     */
    public void setOutputSingleChildHolder(boolean isOutputSingleChildHolder) {
        this.isOutputSingleChildHolder = isOutputSingleChildHolder;
    }

}
