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

import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
import org.onosproject.yangutils.datamodel.YangAugmentableNode;
import org.onosproject.yangutils.datamodel.YangChoice;
import org.onosproject.yangutils.datamodel.YangEnumeration;
import org.onosproject.yangutils.datamodel.YangLeavesHolder;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.datamodel.YangUnion;
import org.onosproject.yangutils.translator.tojava.JavaAttributeInfo;
import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
import org.onosproject.yangutils.translator.tojava.JavaFileInfoContainer;
import org.onosproject.yangutils.translator.tojava.JavaFileInfoTranslator;
import org.onosproject.yangutils.translator.tojava.JavaImportData;
import org.onosproject.yangutils.translator.tojava.JavaQualifiedTypeInfoTranslator;
import org.onosproject.yangutils.translator.tojava.TempJavaCodeFragmentFilesContainer;
import org.onosproject.yangutils.translator.tojava.TempJavaEnumerationFragmentFiles;
import org.onosproject.yangutils.translator.tojava.TempJavaEventFragmentFiles;
import org.onosproject.yangutils.translator.tojava.TempJavaServiceFragmentFiles;
import org.onosproject.yangutils.translator.tojava.TempJavaTypeFragmentFiles;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static java.util.Collections.sort;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.BUILDER_CLASS_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.BUILDER_INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.DEFAULT_CLASS_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_ENUM_CLASS;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_EVENT_CLASS;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_EVENT_LISTENER_INTERFACE;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_EVENT_SUBJECT_CLASS;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_KEY_CLASS;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_SERVICE_AND_MANAGER;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_TYPEDEF_CLASS;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_UNION_CLASS;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.ADD_TO_LIST_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.ADD_TO_LIST_INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.ATTRIBUTES_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.CONSTRUCTOR_FOR_TYPE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.CONSTRUCTOR_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.ENUM_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.EQUALS_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.EVENT_ENUM_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.EVENT_METHOD_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.EVENT_SUBJECT_ATTRIBUTE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.EVENT_SUBJECT_GETTER_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.EVENT_SUBJECT_SETTER_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.FROM_STRING_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.GETTER_FOR_CLASS_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.GETTER_FOR_INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.HASH_CODE_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.LEAF_IDENTIFIER_ENUM_ATTRIBUTES_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.OF_STRING_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.RPC_INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.SETTER_FOR_CLASS_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.SETTER_FOR_INTERFACE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.TO_STRING_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.TempJavaFragmentFiles.getCurNodeAsAttributeInTarget;
import static org.onosproject.yangutils.translator.tojava.TempJavaFragmentFiles.getListOfAttributesForKey;
import static org.onosproject.yangutils.translator.tojava.YangJavaModelUtils.isGetSetOfRootNodeRequired;
import static org.onosproject.yangutils.translator.tojava.utils.IndentationType.FOUR_SPACE;
import static org.onosproject.yangutils.translator.tojava.utils.JavaCodeSnippetGen.getEnumsValueAttribute;
import static org.onosproject.yangutils.translator.tojava.utils.JavaCodeSnippetGen.getEventEnumTypeStart;
import static org.onosproject.yangutils.translator.tojava.utils.JavaCodeSnippetGen.getJavaAttributeDefinition;
import static org.onosproject.yangutils.translator.tojava.utils.JavaCodeSnippetGen.getOperationTypeEnum;
import static org.onosproject.yangutils.translator.tojava.utils.JavaCodeSnippetGen.getSetValueParaForUnionClass;
import static org.onosproject.yangutils.translator.tojava.utils.JavaFileGeneratorUtils.getDataFromTempFileHandle;
import static org.onosproject.yangutils.translator.tojava.utils.JavaFileGeneratorUtils.initiateJavaFileGeneration;
import static org.onosproject.yangutils.translator.tojava.utils.MethodBodyTypes.ENUM_METHOD_INT_VALUE;
import static org.onosproject.yangutils.translator.tojava.utils.MethodBodyTypes.ENUM_METHOD_STRING_VALUE;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.builderMethod;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.generateBuildMethodForSubTree;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getAddAugmentInfoMethodImpl;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getAddAugmentInfoMethodInterface;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getAugmentsDataMethodForService;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getBitSetEnumClassFromString;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getBitSetEnumClassToString;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getCompareToForKeyClass;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getConstructorStart;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getEnumsConstructor;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getEnumsOfValueMethod;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getEqualsMethod;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getEqualsMethodClose;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getEqualsMethodOpen;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getFromStringMethodClose;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getFromStringMethodSignature;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getGetter;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getGetterForClass;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getGetterString;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getHashCodeMethod;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getHashCodeMethodClose;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getHashCodeMethodOpen;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getInterfaceLeafIdEnumSignature;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getRangeValidatorMethodForUnion;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getSetterForClass;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getSetterForSelectLeaf;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getSetterString;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getToStringForEnumClass;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getToStringForType;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getToStringMethodClose;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getToStringMethodOpen;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getUnionToStringMethod;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getYangAugmentInfoImpl;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getYangAugmentInfoInterface;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.isLeafValueSetInterface;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.isSelectLeafSetInterface;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.setSelectLeafSetInterface;
import static org.onosproject.yangutils.translator.tojava.utils.StringGenerator.getImportString;
import static org.onosproject.yangutils.translator.tojava.utils.StringGenerator.getInterfaceLeafIdEnumMethods;
import static org.onosproject.yangutils.translator.tojava.utils.StringGenerator.getIsSelectLeafSet;
import static org.onosproject.yangutils.translator.tojava.utils.StringGenerator.getIsValueLeafSet;
import static org.onosproject.yangutils.translator.tojava.utils.StringGenerator.methodClose;
import static org.onosproject.yangutils.translator.tojava.utils.StringGenerator.signatureClose;
import static org.onosproject.yangutils.translator.tojava.utils.SubtreeFilteringMethodsGenerator.getAugmentableSubTreeFiltering;
import static org.onosproject.yangutils.translator.tojava.utils.SubtreeFilteringMethodsGenerator.getProcessChildNodeSubtreeFiltering;
import static org.onosproject.yangutils.translator.tojava.utils.SubtreeFilteringMethodsGenerator.getProcessLeafListSubtreeFiltering;
import static org.onosproject.yangutils.translator.tojava.utils.SubtreeFilteringMethodsGenerator.getProcessLeafSubtreeFiltering;
import static org.onosproject.yangutils.translator.tojava.utils.SubtreeFilteringMethodsGenerator.getProcessSubTreeFilteringEnd;
import static org.onosproject.yangutils.translator.tojava.utils.SubtreeFilteringMethodsGenerator.getProcessSubTreeForChoiceInterface;
import static org.onosproject.yangutils.translator.tojava.utils.SubtreeFilteringMethodsGenerator.getProcessSubtreeFilteringStart;
import static org.onosproject.yangutils.translator.tojava.utils.SubtreeFilteringMethodsGenerator.getProcessSubtreeFunctionBody;
import static org.onosproject.yangutils.translator.tojava.utils.TranslatorUtils.addDefaultConstructor;
import static org.onosproject.yangutils.translator.tojava.utils.TranslatorUtils.getBeanFiles;
import static org.onosproject.yangutils.translator.tojava.utils.TranslatorUtils.getTypeFiles;
import static org.onosproject.yangutils.utils.UtilConstants.BIG_INTEGER;
import static org.onosproject.yangutils.utils.UtilConstants.BUILDER;
import static org.onosproject.yangutils.utils.UtilConstants.BUILDER_CLASS;
import static org.onosproject.yangutils.utils.UtilConstants.BUILDER_INTERFACE;
import static org.onosproject.yangutils.utils.UtilConstants.CLOSE_CURLY_BRACKET;
import static org.onosproject.yangutils.utils.UtilConstants.COMMA;
import static org.onosproject.yangutils.utils.UtilConstants.DEFAULT;
import static org.onosproject.yangutils.utils.UtilConstants.DEFAULT_CAPS;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.ENUM_CLASS;
import static org.onosproject.yangutils.utils.UtilConstants.EVENT_CLASS;
import static org.onosproject.yangutils.utils.UtilConstants.EVENT_LISTENER_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.EVENT_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.EVENT_SUBJECT_NAME_SUFFIX;
import static org.onosproject.yangutils.utils.UtilConstants.IMPL_CLASS;
import static org.onosproject.yangutils.utils.UtilConstants.INT;
import static org.onosproject.yangutils.utils.UtilConstants.INTERFACE;
import static org.onosproject.yangutils.utils.UtilConstants.JAVA_UTIL_OBJECTS_IMPORT_CLASS;
import static org.onosproject.yangutils.utils.UtilConstants.JAVA_UTIL_PKG;
import static org.onosproject.yangutils.utils.UtilConstants.KEYS;
import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;
import static org.onosproject.yangutils.utils.UtilConstants.OP_PARAM;
import static org.onosproject.yangutils.utils.UtilConstants.PRIVATE;
import static org.onosproject.yangutils.utils.UtilConstants.PROTECTED;
import static org.onosproject.yangutils.utils.UtilConstants.PUBLIC;
import static org.onosproject.yangutils.utils.UtilConstants.RPC_CLASS;
import static org.onosproject.yangutils.utils.UtilConstants.SEMI_COLON;
import static org.onosproject.yangutils.utils.UtilConstants.SERVICE_METHOD_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.TYPEDEF_CLASS;
import static org.onosproject.yangutils.utils.UtilConstants.UNION_CLASS;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.GETTER_METHOD;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.MANAGER_SETTER_METHOD;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.getJavaDoc;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCamelCase;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.insertDataIntoJavaFile;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.replaceLast;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.trimAtLast;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.validateLineLength;

/**
 * Representation of java file generator.
 */
public final class JavaFileGenerator {

    // No instantiation
    private JavaFileGenerator() {
    }

    /**
     * Returns generated interface file for current node.
     *
     * @param file        file
     * @param imports     imports for the file
     * @param curNode     current YANG node
     * @param attrPresent if any attribute is present or not
     * @return interface file
     * @throws IOException when fails to write in file
     */
    public static File generateInterfaceFile(File file, List<String> imports,
                                             YangNode curNode,
                                             boolean attrPresent)
            throws IOException {

        JavaFileInfoTranslator fileInfo =
                ((JavaFileInfoContainer) curNode).getJavaFileInfo();

        String path;
        if (curNode instanceof RpcNotificationContainer) {
            path = fileInfo.getPluginConfig().getCodeGenDir() +
                    fileInfo.getPackageFilePath();
        } else {
            path = fileInfo.getBaseCodeGenPath() +
                    fileInfo.getPackageFilePath();
        }

        String className = getCapitalCase(fileInfo.getJavaName());

        boolean leavesPresent;
        YangLeavesHolder leavesHolder;
        if (curNode instanceof YangLeavesHolder) {
            leavesHolder = (YangLeavesHolder) curNode;
            leavesPresent = leavesPresent(leavesHolder);
        } else {
            leavesPresent = false;
        }

        initiateJavaFileGeneration(file, INTERFACE_MASK, imports, curNode,
                                   className);

        // Generate ENUM interface
        if (curNode instanceof RpcNotificationContainer) {
            insertDataIntoJavaFile(file, getOperationTypeEnum());
        }
        List<String> methods = new ArrayList<>();

        //Add only for choice class
        if (curNode instanceof YangChoice) {
            insertDataIntoJavaFile(file, getProcessSubTreeForChoiceInterface(
                    curNode));
        }

        if (attrPresent) {
            // Add getter methods to interface file.
            try {
                //Leaf identifier enum.
                if (leavesPresent) {
                    insertDataIntoJavaFile(file, getInterfaceLeafIdEnumSignature(
                            className) + trimAtLast(replaceLast(
                            getDataFromTempFileHandle(
                                    LEAF_IDENTIFIER_ENUM_ATTRIBUTES_MASK,
                                    getBeanFiles(curNode), path),
                            COMMA, SEMI_COLON), NEW_LINE) +
                            getInterfaceLeafIdEnumMethods());
                }

                insertDataIntoJavaFile(file, NEW_LINE);
                //Getter methods.
                insertDataIntoJavaFile(file, getDataFromTempFileHandle(
                        GETTER_FOR_INTERFACE_MASK, getBeanFiles(curNode), path));
            } catch (IOException e) {
                throw new IOException(getErrorMsg(className, INTERFACE));
            }
        }

        if (curNode instanceof YangAugmentableNode &&
                !(curNode instanceof YangChoice)) {
            methods.add(getYangAugmentInfoInterface());
        }

        if (leavesPresent) {
            methods.add(isLeafValueSetInterface());
            if (curNode.isOpTypeReq()) {
                methods.add(isSelectLeafSetInterface());
            }
        }
        for (String method : methods) {
            insertDataIntoJavaFile(file, method);
        }
        return file;
    }

    /**
     * Returns generated builder interface file for current node.
     *
     * @param file        file
     * @param curNode     current YANG node
     * @param attrPresent if any attribute is present or not
     * @return builder interface file
     * @throws IOException when fails to write in file
     */
    public static File generateBuilderInterfaceFile(File file, YangNode curNode,
                                                    boolean attrPresent)
            throws IOException {

        JavaFileInfoTranslator fileInfo =
                ((JavaFileInfoContainer) curNode).getJavaFileInfo();

        boolean leavesPresent;
        YangLeavesHolder leavesHolder;
        if (curNode instanceof YangLeavesHolder &&
                curNode.isOpTypeReq()) {
            leavesHolder = (YangLeavesHolder) curNode;
            leavesPresent = leavesPresent(leavesHolder);
        } else {
            leavesPresent = false;
        }

        String className = getCapitalCase(fileInfo.getJavaName());
        String path;
        if (curNode instanceof RpcNotificationContainer) {
            path = fileInfo.getPluginConfig().getCodeGenDir() +
                    fileInfo.getPackageFilePath();
        } else {
            path = fileInfo.getBaseCodeGenPath() +
                    fileInfo.getPackageFilePath();
        }

        initiateJavaFileGeneration(file, BUILDER_INTERFACE_MASK, null, curNode,
                                   className);
        List<String> methods = new ArrayList<>();
        if (attrPresent) {
            try {
                //Getter methods.
                methods.add(getDataFromTempFileHandle(
                        GETTER_FOR_INTERFACE_MASK,
                        getBeanFiles(curNode), path));

                //Setter methods.
                methods.add(getDataFromTempFileHandle(
                        SETTER_FOR_INTERFACE_MASK,
                        getBeanFiles(curNode), path));

                //Add to list method.
                insertDataIntoJavaFile(file, getDataFromTempFileHandle(
                        ADD_TO_LIST_INTERFACE_MASK, getBeanFiles(curNode), path));
            } catch (IOException e) {
                throw new IOException(getErrorMsg(className, BUILDER_INTERFACE));
            }
        }

        if (curNode instanceof YangAugmentableNode &&
                !(curNode instanceof YangChoice)) {
            methods.add(getAddAugmentInfoMethodInterface(className + BUILDER));
            methods.add(getYangAugmentInfoInterface());
        }

        if (leavesPresent) {
            methods.add(setSelectLeafSetInterface(className));
        }
        //Add build method to builder interface file.
        methods.add(((TempJavaCodeFragmentFilesContainer) curNode)
                            .getTempJavaCodeFragmentFiles()
                            .addBuildMethodForInterface());

        //Add getters and setters in builder interface.
        for (String method : methods) {
            insertDataIntoJavaFile(file, method);
        }

        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET + NEW_LINE);
        return file;
    }

    /**
     * Returns generated builder class file for current node.
     *
     * @param file        file
     * @param curNode     current YANG node
     * @param attrPresent if any attribute is present or not
     * @return builder class file
     * @throws IOException when fails to write in file
     */
    public static File generateBuilderClassFile(File file, YangNode curNode,
                                                boolean attrPresent)
            throws IOException {

        JavaFileInfoTranslator fileInfo =
                ((JavaFileInfoContainer) curNode).getJavaFileInfo();

        boolean leavesPresent;
        YangLeavesHolder leavesHolder;
        if (curNode instanceof YangLeavesHolder) {
            leavesHolder = (YangLeavesHolder) curNode;
            leavesPresent = leavesPresent(leavesHolder);
        } else {
            leavesPresent = false;
        }

        String className = getCapitalCase(fileInfo.getJavaName());
        String path;
        if (curNode instanceof RpcNotificationContainer) {
            path = fileInfo.getPluginConfig().getCodeGenDir() +
                    fileInfo.getPackageFilePath();
        } else {
            path = fileInfo.getBaseCodeGenPath() +
                    fileInfo.getPackageFilePath();
        }

        initiateJavaFileGeneration(file, BUILDER_CLASS_MASK, null, curNode,
                                   className);
        List<String> methods = new ArrayList<>();
        if (attrPresent) {

            //Add attribute strings.
            try {
                insertDataIntoJavaFile(file, getDataFromTempFileHandle(
                        ATTRIBUTES_MASK, getBeanFiles(curNode), path));
            } catch (IOException e) {
                throw new IOException(getErrorMsg(className, BUILDER_CLASS));
            }
            try {
                //Getter methods.
                methods.add(getDataFromTempFileHandle(
                        GETTER_FOR_CLASS_MASK, getBeanFiles(curNode), path));
                // Setter methods.
                methods.add(getDataFromTempFileHandle(
                        SETTER_FOR_CLASS_MASK, getBeanFiles(curNode), path));

                //Add to list impl method.
                methods.add(getDataFromTempFileHandle(
                        ADD_TO_LIST_IMPL_MASK, getBeanFiles(curNode), path));

                insertDataIntoJavaFile(file, NEW_LINE);

                //Add operation attribute methods.
                if (leavesPresent && curNode.isOpTypeReq()) {
                    insertDataIntoJavaFile(file, NEW_LINE);
                    methods.add(getSetterForSelectLeaf(className));
                }
            } catch (IOException e) {
                throw new IOException(getErrorMsg(className, BUILDER_CLASS));
            }
        } else {
            insertDataIntoJavaFile(file, NEW_LINE);
        }

        if (curNode instanceof YangAugmentableNode) {
            methods.add(getAddAugmentInfoMethodImpl(className + BUILDER));
            methods.add(getYangAugmentInfoImpl());
        }

        // Add default constructor and build method impl.
        methods.add(((TempJavaCodeFragmentFilesContainer) curNode)
                            .getTempJavaCodeFragmentFiles()
                            .addBuildMethodImpl());
        if (curNode.isOpTypeReq()) {
            methods.add(generateBuildMethodForSubTree(curNode));
        }
        methods.add(addDefaultConstructor(curNode, PUBLIC, BUILDER));

        //Add methods in builder class.
        for (String method : methods) {
            insertDataIntoJavaFile(file, method);
        }
        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET);
        return file;
    }

    /**
     * Returns generated key class file for current list node.
     *
     * @param file    file
     * @param curNode current YANG node
     * @return key class file
     * @throws IOException when fails to write in file
     */
    public static File generateKeyClassFile(File file, YangNode curNode)
            throws IOException {

        JavaFileInfoTranslator fileInfo =
                ((JavaFileInfoContainer) curNode).getJavaFileInfo();

        String className = getCapitalCase(fileInfo.getJavaName()) + KEYS;
        List<String> imports = new ArrayList<>();

        YangNode parent = curNode.getParent();
        JavaImportData importData = ((JavaCodeGeneratorInfo) parent)
                .getTempJavaCodeFragmentFiles().getBeanTempFiles()
                .getJavaImportData();
        JavaQualifiedTypeInfoTranslator info =
                new JavaQualifiedTypeInfoTranslator();
        info.setClassInfo(className);
        info.setPkgInfo(fileInfo.getPackage());
        importData.addImportInfo(info, parent.getJavaClassNameOrBuiltInType(),
                                 parent.getJavaPackage());
        List<JavaAttributeInfo> attrs = getListOfAttributesForKey(curNode);

        Iterator<JavaAttributeInfo> attrIt = attrs.iterator();
        JavaAttributeInfo attr;
        JavaQualifiedTypeInfoTranslator typeInfo;
        while (attrIt.hasNext()) {
            attr = attrIt.next();
            typeInfo = attr.getImportInfo();
            if (!typeInfo.getClassInfo().equals(className)) {
                imports.add(getImportString(attr.getImportInfo().getPkgInfo(),
                                            attr.getImportInfo().getClassInfo()));
            } else {
                attr.setIsQualifiedAccess(true);
            }
        }

        imports.add(getImportString(JAVA_UTIL_PKG,
                                    JAVA_UTIL_OBJECTS_IMPORT_CLASS));

        initiateJavaFileGeneration(file, GENERATE_KEY_CLASS, imports, curNode,
                                   className);
        String pkg = null;
        attrIt = attrs.iterator();
        while (attrIt.hasNext()) {
            attr = attrIt.next();
            if (attr.isQualifiedName()) {
                pkg = attr.getImportInfo().getPkgInfo();
            }
            insertDataIntoJavaFile(file, getJavaAttributeDefinition(
                    pkg, attr.getImportInfo().getClassInfo(),
                    attr.getAttributeName(), false, PROTECTED, null));
        }
        attrIt = attrs.iterator();
        while (attrIt.hasNext()) {
            attr = attrIt.next();
            //add getter methods
            insertDataIntoJavaFile(file, getJavaDoc(GETTER_METHOD, attr
                    .getAttributeName(), false, null));
            insertDataIntoJavaFile(file, getGetterForClass(
                    attr, GENERATE_KEY_CLASS));
            insertDataIntoJavaFile(file, NEW_LINE);
            //Add setter methods.
            insertDataIntoJavaFile(file, getJavaDoc(MANAGER_SETTER_METHOD, attr
                    .getAttributeName(), false, null));
            insertDataIntoJavaFile(file, getSetterForClass(
                    attr, className, GENERATE_EVENT_SUBJECT_CLASS));
            insertDataIntoJavaFile(file, NEW_LINE);
        }
        //add hashcode and equals method.
        insertDataIntoJavaFile(file, getHashCodeMethodOpen());
        StringBuilder builder = new StringBuilder();
        for (JavaAttributeInfo att : attrs) {
            builder.append(getHashCodeMethod(att));
        }
        insertDataIntoJavaFile(file, getHashCodeMethodClose(builder.toString()));

        insertDataIntoJavaFile(file, getEqualsMethodOpen(className));
        StringBuilder builder2 = new StringBuilder();
        for (JavaAttributeInfo att : attrs) {
            builder2.append(getEqualsMethod(att)).append(NEW_LINE);
        }
        insertDataIntoJavaFile(file, getEqualsMethodClose(builder2.toString()));


        insertDataIntoJavaFile(file, getCompareToForKeyClass(attrs, className));

        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET);
        return file;
    }

    /**
     * Returns generated default class file for current node.
     *
     * @param file        file
     * @param curNode     current YANG node
     * @param attrPresent if any attribute is present or not
     * @param imports     list of imports
     * @return impl class file
     * @throws IOException when fails to write in file
     */
    public static File generateDefaultClassFile(File file, YangNode curNode,
                                                boolean attrPresent,
                                                List<String> imports)
            throws IOException {

        JavaFileInfoTranslator fileInfo =
                ((JavaFileInfoContainer) curNode).getJavaFileInfo();
        boolean leavesPresent;
        YangLeavesHolder leavesHolder;
        if (curNode instanceof YangLeavesHolder) {
            leavesHolder = (YangLeavesHolder) curNode;
            leavesPresent = leavesPresent(leavesHolder);
        } else {
            leavesPresent = false;
        }

        boolean rootNode = false;

        String className = getCapitalCase(fileInfo.getJavaName());
        String opParamClassName = className;
        String name = DEFAULT_CAPS + className;
        String path;
        if (curNode instanceof RpcNotificationContainer) {
            opParamClassName = className + OP_PARAM;
            name = opParamClassName;
            rootNode = true;
            path = fileInfo.getPluginConfig().getCodeGenDir() +
                    fileInfo.getPackageFilePath();
        } else {
            path = fileInfo.getBaseCodeGenPath() +
                    fileInfo.getPackageFilePath();
        }

        initiateJavaFileGeneration(file, DEFAULT_CLASS_MASK, imports, curNode,
                                   className);

        List<String> methods = new ArrayList<>();
        if (attrPresent) {
            addDefaultClassAttributeInfo(file, curNode, className,
                                         opParamClassName, path, methods,
                                         rootNode);
        } else {
            insertDataIntoJavaFile(file, NEW_LINE);
        }

        if (curNode instanceof YangAugmentableNode) {
            methods.add(getYangAugmentInfoImpl());
        }
        try {
            //Constructor.
            String constructor = getConstructorStart(className, rootNode) +
                    getDataFromTempFileHandle(
                            CONSTRUCTOR_IMPL_MASK, getBeanFiles(curNode), path)
                    + methodClose(FOUR_SPACE);
            methods.add(constructor);
            if (curNode.isOpTypeReq()) {
                String augmentableSubTreeFiltering = EMPTY_STRING;
                if (curNode instanceof YangAugmentableNode) {
                    // add is filter content match.
                    augmentableSubTreeFiltering = getAugmentableSubTreeFiltering();
                }
                methods.add(getProcessSubtreeFilteringStart(curNode) +
                                    getProcessSubtreeFunctionBody(curNode) +
                                    augmentableSubTreeFiltering +
                                    getProcessSubTreeFilteringEnd(name));

                if (curNode instanceof YangLeavesHolder) {
                    if (((YangLeavesHolder) curNode).getListOfLeaf() != null &&
                            !((YangLeavesHolder) curNode).getListOfLeaf().isEmpty()) {
                        methods.add(getProcessLeafSubtreeFiltering(curNode,
                                                                   path));
                    }
                    if (((YangLeavesHolder) curNode).getListOfLeafList() != null &&
                            !((YangLeavesHolder) curNode).getListOfLeafList().isEmpty()) {
                        methods.add(getProcessLeafListSubtreeFiltering(curNode,
                                                                       path));
                    }
                }

                if (curNode.getChild() != null) {
                    methods.add(getProcessChildNodeSubtreeFiltering(curNode,
                                                                    path));
                }
            }
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, IMPL_CLASS));
        }

        methods.add(addDefaultConstructor(curNode, PROTECTED, DEFAULT));

        methods.add(builderMethod(className));
        if (leavesPresent) {
            methods.add(getIsValueLeafSet());
            if (curNode.isOpTypeReq()) {
                methods.add(getIsSelectLeafSet());
            }
        }
        // Add methods in impl class.
        for (String method : methods) {
            insertDataIntoJavaFile(file, method);
        }

        return file;
    }

    /**
     * Add methods related to attributes.
     *
     * @param file             file
     * @param curNode          current YANG node
     * @param className        name of the class
     * @param opParamClassName op param class name
     * @param path             file path
     * @param methods          list of methods string
     * @param rootNode         flag indicating whether node is root node
     * @throws IOException a violation in IO rule
     */
    private static void addDefaultClassAttributeInfo(File file, YangNode curNode,
                                                     String className,
                                                     String opParamClassName,
                                                     String path, List<String> methods,
                                                     boolean rootNode)
            throws IOException {

        //Add attribute strings.
        try {
            insertDataIntoJavaFile(file, getDataFromTempFileHandle(
                    ATTRIBUTES_MASK, getBeanFiles(curNode), path));
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, IMPL_CLASS));
        }

        try {
            //Getter methods.
            methods.add(getDataFromTempFileHandle(
                    GETTER_FOR_CLASS_MASK, getBeanFiles(curNode), path));

            // Hash code method.
            methods.add(getHashCodeMethodClose(
                    getHashCodeMethodOpen() + getDataFromTempFileHandle(
                            HASH_CODE_IMPL_MASK, getBeanFiles(curNode), path)
                            .replace(NEW_LINE, EMPTY_STRING)));

            //Equals method.
            if (rootNode) {
                methods.add(getEqualsMethodClose(
                        getEqualsMethodOpen(opParamClassName) +
                                getDataFromTempFileHandle(
                                        EQUALS_IMPL_MASK,
                                        getBeanFiles(curNode), path)));
            } else {
                methods.add(getEqualsMethodClose(
                        getEqualsMethodOpen(DEFAULT_CAPS + className) +
                                getDataFromTempFileHandle(EQUALS_IMPL_MASK,
                                                          getBeanFiles(curNode),
                                                          path)));
            }
            // To string method.
            methods.add(getToStringMethodOpen() + getDataFromTempFileHandle(
                    TO_STRING_IMPL_MASK, getBeanFiles(curNode), path) +
                                getToStringMethodClose());
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, IMPL_CLASS));
        }
    }

    /**
     * Generates class file for type def.
     *
     * @param file    generated file
     * @param curNode current YANG node
     * @param imports imports for file
     * @return type def class file
     * @throws IOException when fails to generate class file
     */
    public static File generateTypeDefClassFile(File file, YangNode curNode,
                                                List<String> imports)
            throws IOException {

        JavaFileInfoTranslator fileInfo =
                ((JavaFileInfoContainer) curNode).getJavaFileInfo();
        // import
        String className = getCapitalCase(fileInfo.getJavaName());
        String path = fileInfo.getBaseCodeGenPath() +
                fileInfo.getPackageFilePath();
        initiateJavaFileGeneration(file, className, GENERATE_TYPEDEF_CLASS,
                                   imports, path);

        List<String> methods = new ArrayList<>();
        insertDataIntoJavaFile(file, NEW_LINE);
        //Add attribute strings.
        try {
            insertDataIntoJavaFile(file, getDataFromTempFileHandle(
                    ATTRIBUTES_MASK, getTypeFiles(curNode), path));
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, TYPEDEF_CLASS));
        }

        //Default constructor.
        methods.add(addDefaultConstructor(curNode, PRIVATE, EMPTY_STRING));

        try {

            //Type constructor.
            methods.add(getDataFromTempFileHandle(
                    CONSTRUCTOR_FOR_TYPE_MASK, getTypeFiles(curNode), path));

            //Of method.
            methods.add(getDataFromTempFileHandle(
                    OF_STRING_IMPL_MASK, getTypeFiles(curNode), path));

            //Getter methods.
            methods.add(getDataFromTempFileHandle(
                    GETTER_FOR_CLASS_MASK, getTypeFiles(curNode), path));

            // Hash code method.
            methods.add(getHashCodeMethodClose(
                    getHashCodeMethodOpen() + getDataFromTempFileHandle(
                            HASH_CODE_IMPL_MASK, getTypeFiles(curNode), path)
                            .replace(NEW_LINE, EMPTY_STRING)));

            //Equals method.
            methods.add(getEqualsMethodClose(
                    getEqualsMethodOpen(className + EMPTY_STRING) +
                            getDataFromTempFileHandle(EQUALS_IMPL_MASK,
                                                      getTypeFiles(curNode), path)));

            // To string method.
            addTypedefToString(curNode, methods);

            JavaCodeGeneratorInfo javaGenInfo = (JavaCodeGeneratorInfo) curNode;

            //From string method.
            methods.add(getFromStringMethodSignature(className) +
                                getDataFromTempFileHandle(
                                        FROM_STRING_IMPL_MASK,
                                        javaGenInfo.getTempJavaCodeFragmentFiles()
                                                .getTypeTempFiles(), path) +
                                getFromStringMethodClose());
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, TYPEDEF_CLASS));
        }

        for (String method : methods) {
            insertDataIntoJavaFile(file, method);
        }
        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET + NEW_LINE);

        return validateLineLength(file);
    }

    /**
     * Adds typedef to string method.
     *
     * @param curNode current node
     * @param methods list of methods string
     */
    private static void addTypedefToString(YangNode curNode,
                                           List<String> methods) {
        //To string method.

        List<YangType<?>> types = ((YangTypeDef) curNode).getTypeList();
        YangType type = types.get(0);
        methods.add(getToStringForType(getCamelCase(type.getDataTypeName(),
                                                    null), type));
    }

    /**
     * Generates class file for union type.
     *
     * @param file    generated file
     * @param curNode current YANG node
     * @param imports imports for file
     * @return type def class file
     * @throws IOException when fails to generate class file
     */
    public static File generateUnionClassFile(File file, YangNode curNode,
                                              List<String> imports)
            throws IOException {

        JavaFileInfoTranslator fileInfo =
                ((JavaFileInfoContainer) curNode).getJavaFileInfo();

        String className = getCapitalCase(fileInfo.getJavaName());
        String path = fileInfo.getBaseCodeGenPath() +
                fileInfo.getPackageFilePath();

        TempJavaTypeFragmentFiles tempFiles =
                ((JavaCodeGeneratorInfo) curNode).getTempJavaCodeFragmentFiles()
                        .getTypeTempFiles();

        boolean intConflict = false;
        boolean longConflict = false;
        boolean shortConflict = false;
        JavaAttributeInfo intAttr = tempFiles.getIntAttribute();
        if (intAttr == null) {
            intAttr = tempFiles.getUIntAttribute();
        }

        JavaAttributeInfo longAttr =
                tempFiles.getLongAttribute();
        if (longAttr == null) {
            longAttr = tempFiles.getULongAttribute();
        }

        JavaAttributeInfo shortAttr =
                tempFiles.getShortAttribute();
        if (shortAttr == null) {
            shortAttr = tempFiles.getUInt8Attribute();
        }

        if (intAttr != null) {
            intConflict = intAttr.isIntConflict();
        }
        if (longAttr != null) {
            longConflict = longAttr.isLongConflict();
        }
        if (shortAttr != null) {
            shortConflict = shortAttr.isShortConflict();
        }
        if (longConflict) {
            String impt = tempFiles.getJavaImportData().getBigIntegerImport();
            if (!imports.contains(impt)) {
                imports.add(impt);
                sort(imports);
            }
        }

        initiateJavaFileGeneration(file, className, GENERATE_UNION_CLASS,
                                   imports, path);

        List<String> methods = new ArrayList<>();

        // Add attribute strings.
        try {
            addUnionClassAttributeInfo(file, curNode, intConflict,
                                       longConflict, shortConflict, path, tempFiles);
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, UNION_CLASS));
        }

        //Default constructor.
        methods.add(addDefaultConstructor(curNode, PRIVATE, EMPTY_STRING));

        try {

            //Type constructor.
            methods.add(getDataFromTempFileHandle(
                    CONSTRUCTOR_FOR_TYPE_MASK, getTypeFiles(curNode), path));

            // Of string method.
            methods.add(getDataFromTempFileHandle(
                    OF_STRING_IMPL_MASK, getTypeFiles(curNode), path));

            //Getter methods.
            methods.add(getDataFromTempFileHandle(
                    GETTER_FOR_CLASS_MASK, getTypeFiles(curNode), path));

            //Hash code method.
            methods.add(getHashCodeMethodClose(
                    getHashCodeMethodOpen() +
                            getDataFromTempFileHandle(
                                    HASH_CODE_IMPL_MASK, getTypeFiles(curNode),
                                    path).replace(NEW_LINE, EMPTY_STRING)));

            //Equals method.
            methods.add(getEqualsMethodClose(
                    getEqualsMethodOpen(className) +
                            getDataFromTempFileHandle(
                                    EQUALS_IMPL_MASK, getTypeFiles(curNode),
                                    path)));

            //To string method.
            methods.add(getUnionToStringMethod(
                    ((YangUnion) curNode).getTypeList()));

            //From string method.
            methods.add(getFromStringMethodSignature(className) +
                                getDataFromTempFileHandle(
                                        FROM_STRING_IMPL_MASK,
                                        getTypeFiles(curNode), path) +
                                getFromStringMethodClose());

            if (intConflict) {
                methods.add(getRangeValidatorMethodForUnion(INT));
            }
            if (longConflict) {
                methods.add(getRangeValidatorMethodForUnion(BIG_INTEGER));
            }
            if (shortConflict && !intConflict) {
                methods.add(getRangeValidatorMethodForUnion(INT));
            }
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, UNION_CLASS));
        }

        for (String method : methods) {
            insertDataIntoJavaFile(file, method);
        }
        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET + NEW_LINE);

        return validateLineLength(file);
    }

    /**
     * Adds union class attribute information.
     *
     * @param file          generated file
     * @param curNode       current YANG node
     * @param intConflict   flag to indicate if there is a conflict in int
     * @param longConflict  flag to indicate if there is a conflict in long
     * @param shortConflict flag to indicate if there is a conflict in short
     * @param path          file path
     * @param tempFiles     temp java type fragment files
     * @throws IOException a violation in IO rule
     */
    private static void addUnionClassAttributeInfo(File file,
                                                   YangNode curNode,
                                                   boolean intConflict,
                                                   boolean longConflict,
                                                   boolean shortConflict,
                                                   String path,
                                                   TempJavaTypeFragmentFiles tempFiles)
            throws IOException {
        if (intConflict) {
            insertDataIntoJavaFile(file, JavaCodeSnippetGen
                    .addStaticAttributeIntRange(PRIVATE,
                                                tempFiles.getIntIndex() <
                                                        tempFiles.getUIntIndex()));
        }

        if (longConflict) {
            insertDataIntoJavaFile(file, JavaCodeSnippetGen
                    .addStaticAttributeLongRange(PRIVATE,
                                                 tempFiles.getLongIndex() <
                                                         tempFiles.getULongIndex()));
        }

        if (shortConflict) {
            insertDataIntoJavaFile(file, JavaCodeSnippetGen
                    .addStaticAttributeShortRange(PRIVATE,
                                                  tempFiles.getShortIndex() <
                                                          tempFiles.getUInt8Index()));
        }

        insertDataIntoJavaFile(file, getDataFromTempFileHandle(
                ATTRIBUTES_MASK, getTypeFiles(curNode), path));
        insertDataIntoJavaFile(file, getSetValueParaForUnionClass());
    }

    /**
     * Generates class file for type enum.
     *
     * @param file    generated file
     * @param curNode current YANG node
     * @param imports import list
     * @return class file for type enum
     * @throws IOException when fails to generate class file
     */
    public static File generateEnumClassFile(File file, YangNode curNode, List<String> imports)
            throws IOException {

        JavaFileInfoTranslator fileInfo =
                ((JavaFileInfoContainer) curNode).getJavaFileInfo();

        String className = fileInfo.getJavaName();
        String path = fileInfo.getBaseCodeGenPath() +
                fileInfo.getPackageFilePath();
        TempJavaEnumerationFragmentFiles enumFile = ((JavaCodeGeneratorInfo)
                curNode).getTempJavaCodeFragmentFiles().getEnumTempFiles();
        JavaImportData data = enumFile.getJavaImportData();
        if (!enumFile.isEnumClass()) {
            imports.add(data.getImportForToBitSet());
            imports.add(data.getImportForPattern());
        }

        initiateJavaFileGeneration(file, getCapitalCase(className),
                                   GENERATE_ENUM_CLASS, imports, path);

        //Add attribute strings.
        try {
            JavaCodeGeneratorInfo javaGenInfo = (JavaCodeGeneratorInfo) curNode;
            String[] remove = {COMMA, NEW_LINE};
            insertDataIntoJavaFile(file, trimAtLast(getDataFromTempFileHandle(
                    ENUM_IMPL_MASK, javaGenInfo.getTempJavaCodeFragmentFiles()
                            .getEnumTempFiles(), path), remove) +
                    signatureClose());
        } catch (IOException e) {
            throw new IOException(getErrorMsg(getCapitalCase(className),
                                              ENUM_CLASS));
        }

        insertDataIntoJavaFile(file, NEW_LINE);
        // Add an attribute to get the enum's values.
        insertDataIntoJavaFile(file, getEnumsValueAttribute(className));

        // Add a constructor for enum.
        //TODO: generate javadoc for method.
        insertDataIntoJavaFile(file, getEnumsConstructor(getCapitalCase(className)) +
                NEW_LINE);

        insertDataIntoJavaFile(file,
                               getEnumsOfValueMethod(className,
                                                     (YangEnumeration) curNode,
                                                     ENUM_METHOD_INT_VALUE));
        insertDataIntoJavaFile(file,
                               getEnumsOfValueMethod(className,
                                                     (YangEnumeration) curNode,
                                                     ENUM_METHOD_STRING_VALUE));

        // Add a getter method for enum.
        insertDataIntoJavaFile(file, getJavaDoc(GETTER_METHOD, className, false,
                                                null) +
                getGetter(INT, className, GENERATE_ENUM_CLASS) + NEW_LINE);

        if (!enumFile.isEnumClass()) {
            insertDataIntoJavaFile(file, getBitSetEnumClassFromString
                    (getCapitalCase(className)));
            insertDataIntoJavaFile(file, getBitSetEnumClassToString(
                    getCapitalCase(className), (YangEnumeration) curNode));
        } else {
            insertDataIntoJavaFile(file, getToStringForEnumClass());
        }

        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET + NEW_LINE);

        return validateLineLength(file);
    }

    /**
     * Generates interface file for rpc.
     *
     * @param file    generated file
     * @param curNode current YANG node
     * @param imports imports for file
     * @return rpc class file
     * @throws IOException when fails to generate class file
     */
    public static File generateServiceInterfaceFile(File file, YangNode curNode,
                                                    List<String> imports)
            throws IOException {

        JavaFileInfoTranslator fileInfo =
                ((JavaFileInfoContainer) curNode).getJavaFileInfo();

        TempJavaServiceFragmentFiles tempFiles =
                ((JavaCodeGeneratorInfo) curNode)
                        .getTempJavaCodeFragmentFiles().getServiceTempFiles();
        String className = getCapitalCase(fileInfo.getJavaName()) +
                SERVICE_METHOD_STRING;
        String path = fileInfo.getBaseCodeGenPath() +
                fileInfo.getPackageFilePath();
        initiateJavaFileGeneration(file, GENERATE_SERVICE_AND_MANAGER, imports,
                                   curNode, className);

        List<String> methods = new ArrayList<>();
        JavaAttributeInfo rootAttribute =
                getCurNodeAsAttributeInTarget(curNode, curNode, false,
                                              tempFiles);

        try {

            if (isGetSetOfRootNodeRequired(curNode)) {
                //Getter methods.
                methods.add(getGetterString(rootAttribute,
                                            GENERATE_SERVICE_AND_MANAGER) +
                                    NEW_LINE);
                // Setter methods.
                methods.add(getSetterString(rootAttribute, className,
                                            GENERATE_SERVICE_AND_MANAGER) +
                                    NEW_LINE);
            }

            methods.add(getAugmentsDataMethodForService(curNode));

            if (((JavaCodeGeneratorInfo) curNode).getTempJavaCodeFragmentFiles()
                    .getServiceTempFiles() != null) {
                JavaCodeGeneratorInfo javaGenInfo =
                        (JavaCodeGeneratorInfo) curNode;

                // Rpc methods
                methods.add(getDataFromTempFileHandle(
                        RPC_INTERFACE_MASK,
                        javaGenInfo.getTempJavaCodeFragmentFiles()
                                .getServiceTempFiles(), path));
            }
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, RPC_CLASS));
        }

        for (String method : methods) {
            insertDataIntoJavaFile(file, method);
        }
        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET + NEW_LINE);

        return validateLineLength(file);
    }

    /**
     * Generates event file.
     *
     * @param file    generated file
     * @param curNode current YANG node
     * @param imports imports for file
     * @throws IOException when fails to generate class file
     */
    public static void generateEventFile(File file, YangNode curNode,
                                         List<String> imports)
            throws IOException {

        String className =
                getCapitalCase(((JavaFileInfoContainer) curNode).getJavaFileInfo()
                                       .getJavaName()) + EVENT_STRING;

        TempJavaEventFragmentFiles tempFiles =
                ((TempJavaCodeFragmentFilesContainer) curNode)
                        .getTempJavaCodeFragmentFiles().getEventFragmentFiles();

        String path = ((JavaFileInfoContainer) curNode).getJavaFileInfo()
                .getBaseCodeGenPath() +
                ((JavaFileInfoContainer) curNode).getJavaFileInfo()
                        .getPackageFilePath();
        initiateJavaFileGeneration(file, GENERATE_EVENT_CLASS, imports, curNode,
                                   className);
        try {
            insertDataIntoJavaFile(file, getEventEnumTypeStart() +
                    trimAtLast(getDataFromTempFileHandle(EVENT_ENUM_MASK,
                                                         tempFiles, path),
                               COMMA) + methodClose(FOUR_SPACE));

            insertDataIntoJavaFile(file,
                                   getDataFromTempFileHandle(EVENT_METHOD_MASK,
                                                             tempFiles, path));
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, EVENT_CLASS));
        }

        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET + NEW_LINE);
        validateLineLength(file);
    }

    /**
     * Generates event listener file.
     *
     * @param file    generated file
     * @param curNode current YANG node
     * @param imports imports for file
     * @throws IOException when fails to generate class file
     */
    public static void generateEventListenerFile(File file, YangNode curNode,
                                                 List<String> imports)
            throws IOException {

        String className =
                getCapitalCase(((JavaFileInfoContainer) curNode).getJavaFileInfo()
                                       .getJavaName()) + EVENT_LISTENER_STRING;

        initiateJavaFileGeneration(file, GENERATE_EVENT_LISTENER_INTERFACE,
                                   imports, curNode, className);
        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET + NEW_LINE);
        validateLineLength(file);
    }

    /**
     * Generates event subject's file.
     *
     * @param file    file handle
     * @param curNode current YANG node
     * @throws IOException when fails to do IO exceptions
     */
    public static void generateEventSubjectFile(File file, YangNode curNode)
            throws IOException {

        String className =
                getCapitalCase(((JavaFileInfoContainer) curNode).getJavaFileInfo()
                                       .getJavaName()) + EVENT_SUBJECT_NAME_SUFFIX;

        initiateJavaFileGeneration(file, GENERATE_EVENT_SUBJECT_CLASS, null,
                                   curNode, className);

        String path = ((JavaFileInfoContainer) curNode).getJavaFileInfo()
                .getBaseCodeGenPath() +
                ((JavaFileInfoContainer) curNode).getJavaFileInfo()
                        .getPackageFilePath();

        TempJavaEventFragmentFiles tempFiles =
                ((TempJavaCodeFragmentFilesContainer) curNode)
                        .getTempJavaCodeFragmentFiles().getEventFragmentFiles();

        insertDataIntoJavaFile(file, NEW_LINE);
        try {
            insertDataIntoJavaFile(
                    file, getDataFromTempFileHandle(EVENT_SUBJECT_ATTRIBUTE_MASK,
                                                    tempFiles, path));

            insertDataIntoJavaFile(
                    file, getDataFromTempFileHandle(EVENT_SUBJECT_GETTER_MASK,
                                                    tempFiles, path));

            insertDataIntoJavaFile(
                    file, getDataFromTempFileHandle(EVENT_SUBJECT_SETTER_MASK,
                                                    tempFiles, path));
        } catch (IOException e) {
            throw new IOException(getErrorMsg(className, EVENT_CLASS));
        }

        insertDataIntoJavaFile(file, CLOSE_CURLY_BRACKET + NEW_LINE);
        validateLineLength(file);
    }

    /**
     * Returns error message string.
     *
     * @param className name of the class
     * @param fileType  type of file
     * @return error message string
     */
    private static String getErrorMsg(String className, String fileType) {
        return "No data found in temporary java code fragment files for " +
                className + " while " + fileType + " file generation.";
    }

    /**
     * Checks whether leaf is present in YANG leaves holder.
     *
     * @param holder holder of YANG leaves
     * @return true if leaves are present, false otherwise
     */
    private static boolean leavesPresent(YangLeavesHolder holder) {
        return holder.getListOfLeaf() != null &&
                !holder.getListOfLeaf().isEmpty();
    }

}
