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

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.maven.model.Resource;
import org.apache.maven.project.MavenProject;
import org.onosproject.yangutils.plugin.manager.YangFileInfo;
import org.onosproject.yangutils.translator.tojava.utils.YangPluginConfig;
import org.slf4j.Logger;
import org.sonatype.plexus.build.incremental.BuildContext;

import static org.onosproject.yangutils.utils.UtilConstants.COMMA;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.HASH;
import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;
import static org.onosproject.yangutils.utils.UtilConstants.OPEN_PARENTHESIS;
import static org.onosproject.yangutils.utils.UtilConstants.ORG;
import static org.onosproject.yangutils.utils.UtilConstants.PACKAGE;
import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
import static org.onosproject.yangutils.utils.UtilConstants.SEMI_COLAN;
import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
import static org.onosproject.yangutils.utils.UtilConstants.SPACE;
import static org.onosproject.yangutils.utils.UtilConstants.TEMP;
import static org.onosproject.yangutils.utils.UtilConstants.TWELVE_SPACE_INDENTATION;
import static org.onosproject.yangutils.utils.UtilConstants.YANG_RESOURCES;
import static org.onosproject.yangutils.utils.io.impl.FileSystemUtil.appendFileContents;
import static org.onosproject.yangutils.utils.io.impl.FileSystemUtil.updateFileHandle;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.JavaDocType.PACKAGE_INFO;
import static org.onosproject.yangutils.utils.io.impl.JavaDocGen.getJavaDoc;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Represents common utility functionalities for code generation.
 */
public final class YangIoUtils {

    private static final Logger log = getLogger(YangIoUtils.class);
    private static final String TARGET_RESOURCE_PATH = SLASH + TEMP + SLASH + YANG_RESOURCES + SLASH;
    private static final int LINE_SIZE = 118;
    private static final int SUB_LINE_SIZE = 112;
    private static final int ZERO = 0;

    /**
     * Creates an instance of YANG io utils.
     */
    private YangIoUtils() {
    }

    /**
     * Creates the directory structure.
     *
     * @param path directory path
     * @return directory structure
     */
    public static File createDirectories(String path) {
        File generatedDir = new File(path);
        generatedDir.mkdirs();
        return generatedDir;
    }

    /**
     * Adds package info file for the created directory.
     *
     * @param path         directory path
     * @param classInfo    class info for the package
     * @param pack         package of the directory
     * @param isChildNode  is it a child node
     * @param pluginConfig plugin configurations
     * @throws IOException when fails to create package info file
     */
    public static void addPackageInfo(File path, String classInfo, String pack, boolean isChildNode,
            YangPluginConfig pluginConfig)
            throws IOException {

        pack = parsePkg(pack);

        try {

            File packageInfo = new File(path + SLASH + "package-info.java");
            packageInfo.createNewFile();

            FileWriter fileWriter = new FileWriter(packageInfo);
            BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

            bufferedWriter.write(CopyrightHeader.getCopyrightHeader());
            bufferedWriter.write(getJavaDoc(PACKAGE_INFO, classInfo, isChildNode, pluginConfig));
            String pkg = PACKAGE + SPACE + pack + SEMI_COLAN;
            if (pkg.length() > LINE_SIZE) {
                pkg = whenDelimiterIsPersent(pkg, LINE_SIZE);
            }
            bufferedWriter.write(pkg);
            bufferedWriter.close();
            fileWriter.close();
        } catch (IOException e) {
            throw new IOException("Exception occured while creating package info file.");
        }
    }

    /**
     * Parses package and returns updated package.
     *
     * @param pack package needs to be updated
     * @return updated package
     */
    public static String parsePkg(String pack) {

        if (pack.contains(ORG)) {
            String[] strArray = pack.split(ORG);
            if (strArray.length >= 3) {
                for (int i = 1; i < strArray.length; i++) {
                    if (i == 1) {
                        pack = ORG + strArray[1];
                    } else {
                        pack = pack + ORG + strArray[i];
                    }
                }
            } else {
                pack = ORG + strArray[1];
            }
        }

        return pack;
    }

    /**
     * Cleans the generated directory if already exist in source folder.
     *
     * @param dir generated directory in previous build
     * @throws IOException when failed to delete directory
     */
    public static void deleteDirectory(String dir)
            throws IOException {
        File generatedDirectory = new File(dir);
        if (generatedDirectory.exists()) {
            try {
                FileUtils.deleteDirectory(generatedDirectory);
            } catch (IOException e) {
                throw new IOException(
                        "Failed to delete the generated files in " + generatedDirectory + " directory");
            }
        }
    }

    /**
     * Searches and deletes generated temporary directories.
     *
     * @param root root directory
     * @throws IOException when fails to do IO operations.
     */
    public static void searchAndDeleteTempDir(String root)
            throws IOException {
        List<File> store = new LinkedList<>();
        Stack<String> stack = new Stack<>();
        stack.push(root);

        while (!stack.empty()) {
            root = stack.pop();
            File file = new File(root);
            File[] filelist = file.listFiles();
            if (filelist == null || filelist.length == 0) {
                continue;
            }
            for (File current : filelist) {
                if (current.isDirectory()) {
                    stack.push(current.toString());
                    if (current.getName().endsWith("-Temp")) {
                        store.add(current);
                    }
                }
            }
        }

        for (File dir : store) {
            FileUtils.deleteDirectory(dir);
        }
    }

    /**
     * Adds generated source directory to the compilation root.
     *
     * @param source  directory
     * @param project current maven project
     * @param context current build context
     */
    public static void addToSource(String source, MavenProject project, BuildContext context) {
        project.addCompileSourceRoot(source);
        context.refresh(project.getBasedir());
        log.info("Source directory added to compilation root: " + source);
    }

    /**
     * Removes extra char from the string.
     *
     * @param valueString    string to be trimmed
     * @param removealStirng extra chars
     * @return new string
     */
    public static String trimAtLast(String valueString, String removealStirng) {
        StringBuilder stringBuilder = new StringBuilder(valueString);
        int index = valueString.lastIndexOf(removealStirng);
        stringBuilder.deleteCharAt(index);
        return stringBuilder.toString();
    }

    /**
     * Returns new parted string.
     *
     * @param partString string to be parted
     * @return parted string
     */
    public static String partString(String partString) {
        String[] strArray = partString.split(COMMA);
        String newString = EMPTY_STRING;
        for (int i = 0; i < strArray.length; i++) {
            if (i % 4 != 0 || i == 0) {
                newString = newString + strArray[i] + COMMA;
            } else {
                newString = newString + NEW_LINE + TWELVE_SPACE_INDENTATION
                        + strArray[i] + COMMA;
            }
        }
        return trimAtLast(newString, COMMA);
    }

    /**
     * Returns the directory path of the package in canonical form.
     *
     * @param baseCodeGenPath base path where the generated files needs to be
     *                        put
     * @param pathOfJavaPkg   java package of the file being generated
     * @return absolute path of the package in canonical form
     */
    public static String getDirectory(String baseCodeGenPath, String pathOfJavaPkg) {

        if (pathOfJavaPkg.charAt(pathOfJavaPkg.length() - 1) == File.separatorChar) {
            pathOfJavaPkg = trimAtLast(pathOfJavaPkg, SLASH);
        }
        String[] strArray = pathOfJavaPkg.split(SLASH);
        if (strArray[0].equals(EMPTY_STRING)) {
            return pathOfJavaPkg;
        } else {
            return baseCodeGenPath + SLASH + pathOfJavaPkg;
        }
    }

    /**
     * Returns the absolute path of the package in canonical form.
     *
     * @param baseCodeGenPath base path where the generated files needs to be
     *                        put
     * @param pathOfJavaPkg   java package of the file being generated
     * @return absolute path of the package in canonical form
     */
    public static String getAbsolutePackagePath(String baseCodeGenPath, String pathOfJavaPkg) {
        return baseCodeGenPath + pathOfJavaPkg;
    }

    /**
     * Copies YANG files to the current project's output directory.
     *
     * @param yangFileInfo list of YANG files
     * @param outputDir    project's output directory
     * @param project      maven project
     * @throws IOException when fails to copy files to destination resource directory
     */
    public static void copyYangFilesToTarget(Set<YangFileInfo> yangFileInfo, String outputDir, MavenProject project)
            throws IOException {

        List<File> files = getListOfFile(yangFileInfo);

        String path = outputDir + TARGET_RESOURCE_PATH;
        File targetDir = new File(path);
        targetDir.mkdirs();

        for (File file : files) {
            Files.copy(file.toPath(),
                    new File(path + file.getName()).toPath(),
                    StandardCopyOption.REPLACE_EXISTING);
        }
        Resource rsc = new Resource();
        rsc.setDirectory(outputDir + SLASH + TEMP + SLASH);
        project.addResource(rsc);
    }

    /**
     * Provides a list of files from list of strings.
     *
     * @param yangFileInfo set of yang file information
     * @return list of files
     */
    private static List<File> getListOfFile(Set<YangFileInfo> yangFileInfo) {
        List<File> files = new ArrayList<>();
        Iterator<YangFileInfo> yangFileIterator = yangFileInfo.iterator();
        while (yangFileIterator.hasNext()) {
            YangFileInfo yangFile = yangFileIterator.next();
            files.add(new File(yangFile.getYangFileName()));
        }
        return files;
    }

    /**
     * Merges the temp java files to main java files.
     *
     * @param appendFile temp file
     * @param srcFile    main file
     * @throws IOException when fails to append contents
     */
    public static void mergeJavaFiles(File appendFile, File srcFile)
            throws IOException {
        try {
            appendFileContents(appendFile, srcFile);
        } catch (IOException e) {
            throw new IOException("Failed to append " + appendFile + " in " + srcFile);
        }
    }

    /**
     * Inserts data in the generated file.
     *
     * @param file file in which need to be inserted
     * @param data data which need to be inserted
     * @throws IOException when fails to insert into file
     */
    public static void insertDataIntoJavaFile(File file, String data)
            throws IOException {
        try {
            updateFileHandle(file, data, false);
        } catch (IOException e) {
            throw new IOException("Failed to insert in " + file + "file");
        }
    }

    /**
     * Validates a line size in given file whether it is having more then 120 characters.
     * If yes it will update and give a new file.
     *
     * @param dataFile file in which need to verify all lines.
     * @return updated file
     * @throws IOException when fails to do IO operations.
     */
    public static File validateLineLength(File dataFile)
            throws IOException {
        File tempFile = dataFile;
        FileReader fileReader = new FileReader(dataFile);
        BufferedReader bufferReader = new BufferedReader(fileReader);
        try {
            StringBuilder stringBuilder = new StringBuilder();
            String line = bufferReader.readLine();

            while (line != null) {
                if (line.length() > LINE_SIZE) {
                    if (line.contains(PERIOD)) {
                        line = whenDelimiterIsPersent(line, LINE_SIZE);
                    } else if (line.contains(SPACE)) {
                        line = whenSpaceIsPresent(line, LINE_SIZE);
                    }
                    stringBuilder.append(line);
                } else {
                    stringBuilder.append(line + NEW_LINE);
                }
                line = bufferReader.readLine();
            }
            FileWriter writer = new FileWriter(tempFile);
            writer.write(stringBuilder.toString());
            writer.close();
            return tempFile;
        } finally {
            fileReader.close();
            bufferReader.close();
        }
    }

    /*When delimiters are present in the given line.*/
    private static String whenDelimiterIsPersent(String line, int lineSize) {
        StringBuilder stringBuilder = new StringBuilder();

        if (line.length() > lineSize) {
            String[] strArray = line.split(Pattern.quote(PERIOD));
            stringBuilder = updateString(strArray, stringBuilder, PERIOD, lineSize);
        } else {
            stringBuilder.append(line + NEW_LINE);
        }
        String[] strArray = stringBuilder.toString().split(NEW_LINE);
        StringBuilder tempBuilder = new StringBuilder();
        for (String str : strArray) {
            if (str.length() > SUB_LINE_SIZE) {
                if (line.contains(PERIOD) && !line.contains(PERIOD + HASH + OPEN_PARENTHESIS)) {
                    String[] strArr = str.split(Pattern.quote(PERIOD));
                    tempBuilder = updateString(strArr, tempBuilder, PERIOD, SUB_LINE_SIZE);
                } else if (str.contains(SPACE)) {
                    tempBuilder.append(whenSpaceIsPresent(str, SUB_LINE_SIZE));
                }
            } else {
                tempBuilder.append(str + NEW_LINE);
            }
        }
        return tempBuilder.toString();

    }

    /*When spaces are present in the given line.*/
    private static String whenSpaceIsPresent(String line, int lineSize) {
        StringBuilder stringBuilder = new StringBuilder();
        if (line.length() > lineSize) {
            String[] strArray = line.split(SPACE);
            stringBuilder = updateString(strArray, stringBuilder, SPACE, lineSize);
        } else {
            stringBuilder.append(line + NEW_LINE);
        }

        String[] strArray = stringBuilder.toString().split(NEW_LINE);
        StringBuilder tempBuilder = new StringBuilder();
        for (String str : strArray) {
            if (str.length() > SUB_LINE_SIZE) {
                if (str.contains(SPACE)) {
                    String[] strArr = str.split(SPACE);
                    tempBuilder = updateString(strArr, tempBuilder, SPACE, SUB_LINE_SIZE);
                }
            } else {
                tempBuilder.append(str + NEW_LINE);
            }
        }
        return tempBuilder.toString();
    }

    /*Updates the given line with the given size conditions.*/
    private static StringBuilder updateString(String[] strArray, StringBuilder stringBuilder, String string,
            int lineSize) {

        StringBuilder tempBuilder = new StringBuilder();
        for (String str : strArray) {
            tempBuilder.append(str + string);
            if (tempBuilder.length() > lineSize) {
                String tempString = stringBuilder.toString();
                stringBuilder.delete(ZERO, stringBuilder.length());
                tempString = trimAtLast(tempString, string);
                stringBuilder.append(tempString);
                if (string.equals(PERIOD)) {
                    stringBuilder.append(NEW_LINE + TWELVE_SPACE_INDENTATION + PERIOD + str + string);
                } else {
                    stringBuilder.append(NEW_LINE + TWELVE_SPACE_INDENTATION + str + string);
                }
                tempBuilder.delete(ZERO, tempBuilder.length());
                tempBuilder.append(TWELVE_SPACE_INDENTATION);
            } else {
                stringBuilder.append(str + string);
            }
        }
        String tempString = stringBuilder.toString();
        tempString = trimAtLast(tempString, string);
        stringBuilder.delete(ZERO, stringBuilder.length());
        stringBuilder.append(tempString + NEW_LINE);
        return stringBuilder;
    }
}
