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

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.linker.YangLinker;
import org.onosproject.yangutils.linker.exceptions.LinkerException;
import org.onosproject.yangutils.linker.impl.YangLinkerManager;
import org.onosproject.yangutils.parser.YangUtilsParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import org.onosproject.yangutils.translator.tojava.utils.YangPluginConfig;
import org.onosproject.yangutils.translator.tojava.utils.YangToJavaNamingConflictUtil;
import org.onosproject.yangutils.utils.io.impl.YangFileScanner;
import org.sonatype.plexus.build.incremental.BuildContext;

import static org.apache.maven.plugins.annotations.LifecyclePhase.GENERATE_SOURCES;
import static org.apache.maven.plugins.annotations.ResolutionScope.COMPILE;
import static org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorUtil.generateJavaCode;
import static org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorUtil.translatorErrorHandler;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getPackageDirPathFromJavaJPackage;
import static org.onosproject.yangutils.utils.UtilConstants.DEFAULT_BASE_PKG;
import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;
import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.addToSource;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.copyYangFilesToTarget;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getDirectory;

/**
 * Represents ONOS YANG utility maven plugin.
 * Goal of plugin is yang2java.
 * Execution phase is generate-sources.
 * requiresDependencyResolution at compile time.
 */
@Mojo(name = "yang2java", defaultPhase = GENERATE_SOURCES, requiresDependencyResolution = COMPILE,
        requiresProject = true)
public class YangUtilManager extends AbstractMojo {

    private YangNode rootNode;
    // YANG file information set.
    private Set<YangFileInfo> yangFileInfoSet = new HashSet<>();
    private YangUtilsParser yangUtilsParser = new YangUtilsParserManager();
    private YangLinker yangLinker = new YangLinkerManager();
    private YangFileInfo curYangFileInfo = new YangFileInfo();

    private static final String DEFAULT_PKG = SLASH + getPackageDirPathFromJavaJPackage(DEFAULT_BASE_PKG);

    /**
     * Source directory for YANG files.
     */
    @Parameter(property = "yangFilesDir", defaultValue = "src/main/yang")
    private String yangFilesDir;

    /**
     * Source directory for generated files.
     */
    @Parameter(property = "genFilesDir", defaultValue = "src/main/java")
    private String genFilesDir;

    /**
     * Base directory for project.
     */
    @Parameter(property = "basedir", defaultValue = "${basedir}")
    private String baseDir;

    /**
     * Output directory.
     */
    @Parameter(property = "project.build.outputDirectory", required = true, defaultValue = "target/classes")
    private String outputDirectory;

    /**
     * Current maven project.
     */
    @Parameter(property = "project", required = true, readonly = true, defaultValue = "${project}")
    private MavenProject project;

    /**
     * Replacement required for period special character in the identifier.
     */
    @Parameter(property = "replacementForPeriod")
    private String replacementForPeriod;

    /**
     * Replacement required for underscore special character in the identifier.
     */
    @Parameter(property = "replacementForUnderscore")
    private String replacementForUnderscore;

    /**
     * Replacement required for hyphen special character in the identifier.
     */
    @Parameter(property = "replacementForHyphen")
    private String replacementForHyphen;

    /**
     * Prefix which is required for adding with the identifier.
     */
    @Parameter(property = "prefixForIdentifier")
    private String prefixForIdentifier;

    /**
     * Build context.
     */
    @Component
    private BuildContext context;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {

        try {

            /*
             * For deleting the generated code in previous build.
             */
            deleteDirectory(getDirectory(baseDir, genFilesDir) + DEFAULT_PKG);
            deleteDirectory(getDirectory(baseDir, outputDirectory));

            String searchDir = getDirectory(baseDir, yangFilesDir);
            String codeGenDir = getDirectory(baseDir, genFilesDir) + SLASH;

            // Creates conflict resolver and set values to it.
            YangToJavaNamingConflictUtil conflictResolver = new YangToJavaNamingConflictUtil();
            conflictResolver.setReplacementForPeriod(replacementForPeriod);
            conflictResolver.setReplacementForHyphen(replacementForHyphen);
            conflictResolver.setReplacementForUnderscore(replacementForUnderscore);
            conflictResolver.setPrefixForIdentifier(prefixForIdentifier);
            YangPluginConfig yangPlugin = new YangPluginConfig();
            yangPlugin.setCodeGenDir(codeGenDir);
            yangPlugin.setConflictResolver(conflictResolver);

            /*
             * Obtain the YANG files at a path mentioned in plugin and creates
             * YANG file information set.
             */
            createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));

            // Check if there are any file to translate, if not return.
            if (getYangFileInfoSet() == null || getYangFileInfoSet().isEmpty()) {
                // No files to translate
                return;
            }

            // Carry out the parsing for all the YANG files.
            parseYangFileInfoSet();

            // Resolve dependencies using linker.
            resolveDependenciesUsingLinker();

            // Perform translation to JAVA.
            translateToJava(getYangFileInfoSet(), yangPlugin);

            addToSource(getDirectory(baseDir, genFilesDir), project, context);

            copyYangFilesToTarget(getYangFileInfoSet(), getDirectory(baseDir, outputDirectory), project);
        } catch (IOException | ParserException e) {
            String fileName = "";
            if (getCurYangFileInfo() != null) {
                fileName = getCurYangFileInfo().getYangFileName();
            }
            try {
                translatorErrorHandler(getRootNode());
                deleteDirectory(getDirectory(baseDir, genFilesDir) + DEFAULT_PKG);
            } catch (IOException ex) {
                throw new MojoExecutionException(
                        "Error handler failed to delete files for data model node.");
            }
            throw new MojoExecutionException(
                    "Exception occured due to " + e.getLocalizedMessage() + " in " + fileName
                            + " YANG file.");
        }
    }

    /**
     * Links all the provided with the YANG file info set.
     *
     * @throws MojoExecutionException a violation in mojo excecution
     */
    public void resolveDependenciesUsingLinker() throws MojoExecutionException {
        for (YangFileInfo yangFileInfo : getYangFileInfoSet()) {
            setCurYangFileInfo(yangFileInfo);
            try {
                yangLinker.resolveDependencies(getYangFileInfoSet());
            } catch (LinkerException e) {
                throw new MojoExecutionException(e.getMessage());
            }
        }
    }

    /**
     * Parses all the provided YANG files and generates YANG data model tree.
     *
     * @throws IOException a violation in IO
     */
    public void parseYangFileInfoSet() throws IOException {
        for (YangFileInfo yangFileInfo : getYangFileInfoSet()) {
            setCurYangFileInfo(yangFileInfo);
            try {
                YangNode yangNode = yangUtilsParser.getDataModel(yangFileInfo.getYangFileName());
                yangFileInfo.setRootNode(yangNode);
                setRootNode(yangNode);
            } catch (ParserException e) {
                String logInfo = "Error in file: " + e.getFileName();
                if (e.getLineNumber() != 0) {
                    logInfo = logInfo + " at line: " + e.getLineNumber() + " at position: "
                            + e.getCharPositionInLine();

                }
                if (e.getMessage() != null) {
                    logInfo = logInfo + NEW_LINE + e.getMessage();
                }
                getLog().info(logInfo);
                throw e;
            }
        }
    }

    /**
     * Returns current root YANG node of data-model tree.
     *
     * @return current root YANG node of data-model tree
     */
    private YangNode getRootNode() {
        return rootNode;
    }

    /**
     * Sets current root YANG node of data-model tree.
     *
     * @param rootNode current root YANG node of data-model tree
     */
    private void setRootNode(YangNode rootNode) {
        this.rootNode = rootNode;
    }

    /**
     * Translates to java code corresponding to the YANG schema.
     *
     * @param yangFileInfoSet YANG file information
     * @param yangPlugin      YANG plugin config
     * @throws IOException when fails to generate java code file the current
     *                     node
     */
    public void translateToJava(Set<YangFileInfo> yangFileInfoSet, YangPluginConfig yangPlugin)
            throws IOException {
        Iterator<YangFileInfo> yangFileIterator = yangFileInfoSet.iterator();
        while (yangFileIterator.hasNext()) {
            YangFileInfo yangFileInfo = yangFileIterator.next();
            setCurYangFileInfo(yangFileInfo);
            generateJavaCode(yangFileInfo.getRootNode(), yangPlugin);
        }
    }

    /**
     * Creates a YANG file info set.
     *
     * @param yangFileList YANG files list
     */
    public void createYangFileInfoSet(List<String> yangFileList) {
        for (String yangFile : yangFileList) {
            YangFileInfo yangFileInfo = new YangFileInfo();
            yangFileInfo.setYangFileName(yangFile);
            getYangFileInfoSet().add(yangFileInfo);
        }
    }

    /**
     * Returns the YANG file info set.
     *
     * @return the YANG file info set
     */
    public Set<YangFileInfo> getYangFileInfoSet() {
        return yangFileInfoSet;
    }

    /**
     * Sets the YANG file info set.
     *
     * @param yangFileInfoSet the YANG file info set
     */
    public void setYangFileInfoSet(Set<YangFileInfo> yangFileInfoSet) {
        this.yangFileInfoSet = yangFileInfoSet;
    }

    /**
     * Returns current YANG file's info.
     *
     * @return the yangFileInfo
     */
    public YangFileInfo getCurYangFileInfo() {
        return curYangFileInfo;
    }

    /**
     * Sets current YANG file's info.
     *
     * @param yangFileInfo the yangFileInfo to set
     */
    public void setCurYangFileInfo(YangFileInfo yangFileInfo) {
        this.curYangFileInfo = yangFileInfo;
    }
}
