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

import com.google.common.collect.ImmutableList;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;

import javax.imageio.ImageIO;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.google.common.io.ByteStreams.toByteArray;
import static org.codehaus.plexus.util.FileUtils.*;

/**
 * Produces ONOS application archive using the app.xml file information.
 */
@Mojo(name = "app", defaultPhase = LifecyclePhase.PACKAGE)
public class OnosAppMojo extends AbstractMojo {

    private static final String APP = "app";
    private static final String NAME = "[@name]";
    private static final String VERSION = "[@version]";
    private static final String FEATURES_REPO = "[@featuresRepo]";
    private static final String ARTIFACT = "artifact";

    private static final String APP_XML = "app.xml";
    private static final String APP_PNG = "app.png";
    private static final String FEATURES_XML = "features.xml";

    private static final String MVN_URL = "mvn:";
    private static final String M2_PREFIX = "m2";

    private static final String ONOS_APP_NAME = "onos.app.name";
    private static final String ONOS_APP_ORIGIN = "onos.app.origin";
    private static final String ONOS_APP_REQUIRES = "onos.app.requires";

    private static final String ONOS_APP_CATEGORY = "onos.app.category";
    private static final String ONOS_APP_URL = "onos.app.url";
    private static final String ONOS_APP_TITLE = "onos.app.title";
    private static final String ONOS_APP_README = "onos.app.readme";

    private static final String JAR = "jar";
    private static final String XML = "xml";
    private static final String APP_ZIP = "oar";
    private static final String PACKAGE_DIR = "oar";

    private static final String DEFAULT_ORIGIN = "ON.Lab";
    private static final String DEFAULT_VERSION = "${project.version}";

    private static final String DEFAULT_CATEGORY = "default";
    private static final String DEFAULT_URL = "http://onosproject.org";

    private static final String DEFAULT_FEATURES_REPO =
            "mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features";
    private static final String DEFAULT_ARTIFACT =
            "mvn:${project.groupId}/${project.artifactId}/${project.version}";

    private static final int BUFFER_SIZE = 8192;

    private String name;
    private String origin;
    private String requiredApps;
    private String category;
    private String url;
    private String title;
    private String readme;
    private String version = DEFAULT_VERSION;
    private String featuresRepo = DEFAULT_FEATURES_REPO;
    private List<String> artifacts;

    /**
     * The project base directory.
     */
    @Parameter(defaultValue = "${basedir}")
    protected File baseDir;

    /**
     * The directory where the generated catalogue file will be put.
     */
    @Parameter(defaultValue = "${project.build.directory}")
    protected File dstDirectory;

    /**
     * The project group ID.
     */
    @Parameter(defaultValue = "${project.groupId}")
    protected String projectGroupId;

    /**
     * The project artifact ID.
     */
    @Parameter(defaultValue = "${project.artifactId}")
    protected String projectArtifactId;

    /**
     * The project version.
     */
    @Parameter(defaultValue = "${project.version}")
    protected String projectVersion;

    /**
     * The project version.
     */
    @Parameter(defaultValue = "${project.description}")
    protected String projectDescription;

    @Parameter(defaultValue = "${localRepository}")
    protected ArtifactRepository localRepository;

    /**
     * Maven project
     */
    @Parameter(defaultValue = "${project}")
    protected MavenProject project;

    /**
     * Maven project helper.
     */
    @Component
    protected MavenProjectHelper projectHelper;

    private File m2Directory;
    protected File stageDirectory;
    protected String projectPath;

    @Override
    public void execute() throws MojoExecutionException {
        File appFile = new File(baseDir, APP_XML);
        File iconFile = new File(baseDir, APP_PNG);
        File featuresFile = new File(baseDir, FEATURES_XML);

        name = (String) project.getProperties().get(ONOS_APP_NAME);

        // If neither the app.xml file exists, nor the onos.app.name property
        // is defined, there is nothing for this Mojo to do, so bail.
        if (!appFile.exists() && name == null) {
            return;
        }

        m2Directory = new File(localRepository.getBasedir());
        stageDirectory = new File(dstDirectory, PACKAGE_DIR);
        projectPath = M2_PREFIX + "/" + artifactDir(projectGroupId, projectArtifactId, projectVersion);

        origin = (String) project.getProperties().get(ONOS_APP_ORIGIN);
        origin = origin != null ? origin : DEFAULT_ORIGIN;

        requiredApps = (String) project.getProperties().get(ONOS_APP_REQUIRES);
        requiredApps = requiredApps == null ? "" : requiredApps.replaceAll("[\\s]", "");

        category = (String) project.getProperties().get(ONOS_APP_CATEGORY);
        category = category != null ? category : DEFAULT_CATEGORY;

        url = (String) project.getProperties().get(ONOS_APP_URL);
        url = url != null ? url : DEFAULT_URL;

        // if title does not exist, fall back to the name
        title = (String) project.getProperties().get(ONOS_APP_TITLE);
        title = title != null ? title : name;

        // if readme does not exist, we simply fallback to use description
        readme = (String) project.getProperties().get(ONOS_APP_README);
        readme = readme != null ? readme : projectDescription;

        if (appFile.exists()) {
            loadAppFile(appFile);
        } else {
            artifacts = ImmutableList.of(eval(DEFAULT_ARTIFACT));
        }

        // If there are any artifacts, stage the
        if (!artifacts.isEmpty()) {
            getLog().info("Building ONOS application package for " + name + " (v" + eval(version) + ")");
            artifacts.forEach(a -> getLog().debug("Including artifact: " + a));

            if (stageDirectory.exists() || stageDirectory.mkdirs()) {
                processAppXml(appFile);
                processAppPng(iconFile);
                processFeaturesXml(featuresFile);
                processArtifacts();
                generateAppPackage();
            } else {
                throw new MojoExecutionException("Unable to create directory: " + stageDirectory);
            }
        }
    }

    // Loads the app.xml file.
    private void loadAppFile(File appFile) throws MojoExecutionException {
        XMLConfiguration xml = new XMLConfiguration();
        xml.setRootElementName(APP);

        try (FileInputStream stream = new FileInputStream(appFile)) {
            xml.load(stream);
            xml.setAttributeSplittingDisabled(true);
            xml.setDelimiterParsingDisabled(true);

            name = xml.getString(NAME);
            version = eval(xml.getString(VERSION));
            featuresRepo = eval(xml.getString(FEATURES_REPO));

            artifacts = xml.configurationsAt(ARTIFACT).stream()
                    .map(cfg -> eval(cfg.getRootNode().getValue().toString()))
                    .collect(Collectors.toList());

        } catch (ConfigurationException e) {
            throw new MojoExecutionException("Unable to parse app.xml file", e);
        } catch (FileNotFoundException e) {
            throw new MojoExecutionException("Unable to find app.xml file", e);
        } catch (IOException e) {
            throw new MojoExecutionException("Unable to read app.xml file", e);
        }
    }

    // Processes and stages the app.xml file.
    private void processAppXml(File appFile) throws MojoExecutionException {
        try {
            File file = new File(stageDirectory, APP_XML);
            forceMkdir(stageDirectory);
            String contents;

            if (appFile.exists()) {
                contents = fileRead(appFile);
            } else {
                byte[] bytes = toByteArray(getClass().getResourceAsStream(APP_XML));
                contents = new String(bytes);
            }
            fileWrite(file.getAbsolutePath(), eval(contents));
        } catch (IOException e) {
            throw new MojoExecutionException("Unable to process app.xml", e);
        }
    }

    // Stages the app.png file of a specific application.
    private void processAppPng(File iconFile) throws MojoExecutionException {
        try {
            File stagedIconFile = new File(stageDirectory, APP_PNG);

            if (iconFile.exists()) {
                FileUtils.copyFile(iconFile, stagedIconFile);
            }
        } catch (IOException e) {
            throw new MojoExecutionException("Unable to copy app.png", e);
        }
    }

    private void processFeaturesXml(File featuresFile) throws MojoExecutionException {
        boolean specified = featuresRepo != null && featuresRepo.length() > 0;

        // If featuresRepo attribute is specified and there is a features.xml
        // file present, add the features repo as an artifact
        try {
            if (specified && featuresFile.exists()) {
                processFeaturesXml(new FileInputStream(featuresFile));
            } else if (specified) {
                processFeaturesXml(getClass().getResourceAsStream(FEATURES_XML));
            }
        } catch (FileNotFoundException e) {
            throw new MojoExecutionException("Unable to find features.xml file", e);
        } catch (IOException e) {
            throw new MojoExecutionException("Unable to process features.xml file", e);
        }
    }

    // Processes and stages the features.xml file.
    private void processFeaturesXml(InputStream stream) throws IOException {
        String featuresArtifact =
                artifactFile(projectArtifactId, projectVersion, XML, "features");
        File dstDir = new File(stageDirectory, projectPath);
        forceMkdir(dstDir);
        String s = eval(new String(toByteArray(stream)));
        fileWrite(new File(dstDir, featuresArtifact).getAbsolutePath(), s);
    }

    // Stages all artifacts.
    private void processArtifacts() throws MojoExecutionException {
        for (String artifact : artifacts) {
            processArtifact(artifact);
        }
    }

    // Stages the specified artifact.
    private void processArtifact(String artifact) throws MojoExecutionException {
        if (!artifact.startsWith(MVN_URL)) {
            throw new MojoExecutionException("Unsupported artifact URL:" + artifact);
        }

        String[] fields = artifact.substring(4).split("/");
        if (fields.length < 3) {
            throw new MojoExecutionException("Illegal artifact URL:" + artifact);
        }

        try {
            String file = artifactFile(fields);

            if (projectGroupId.equals(fields[0]) && projectArtifactId.equals(fields[1])) {
                // Local artifact is not installed yet, package it from target directory.
                File dstDir = new File(stageDirectory, projectPath);
                forceMkdir(dstDir);
                copyFile(new File(dstDirectory, file), new File(dstDir, file));
            } else {
                // Other artifacts are packaged from ~/.m2/repository directory.
                String m2Path = artifactDir(fields);
                File srcDir = new File(m2Directory, m2Path);
                File dstDir = new File(stageDirectory, M2_PREFIX + "/" + m2Path);
                forceMkdir(dstDir);
                copyFile(new File(srcDir, file), new File(dstDir, file));
            }
        } catch (IOException e) {
            throw new MojoExecutionException("Unable to stage artifact " + artifact, e);
        }
    }

    // Generates the ONOS package ZIP file.
    private void generateAppPackage() throws MojoExecutionException {
        File appZip = new File(dstDirectory, artifactFile(projectArtifactId, projectVersion,
                APP_ZIP, null));
        try (FileOutputStream fos = new FileOutputStream(appZip);
             ZipOutputStream zos = new ZipOutputStream(fos)) {
            zipDirectory("", stageDirectory, zos);
            projectHelper.attachArtifact(this.project, APP_ZIP, null, appZip);
        } catch (IOException e) {
            throw new MojoExecutionException("Unable to compress application package", e);
        }
    }

    // Generates artifact directory name from the specified fields.
    private String artifactDir(String[] fields) {
        return artifactDir(fields[0], fields[1], fields[2]);
    }

    // Generates artifact directory name from the specified elements.
    private String artifactDir(String gid, String aid, String version) {
        return gid.replace('.', '/') + "/" + aid.replace('.', '/') + "/" + version;
    }

    // Generates artifact file name from the specified fields.
    private String artifactFile(String[] fields) {
        return fields.length < 5 ?
                artifactFile(fields[1], fields[2],
                        (fields.length < 4 ? JAR : fields[3]), null) :
                artifactFile(fields[1], fields[2], fields[3], fields[4]);
    }

    // Generates artifact file name from the specified elements.
    private String artifactFile(String aid, String version, String type,
                                String classifier) {
        return classifier == null ? aid + "-" + version + "." + type :
                aid + "-" + version + "-" + classifier + "." + type;
    }

    // Returns the given string with project variable substitutions.
    private String eval(String string) {
        return string == null ? null :
                string.replaceAll("\\$\\{onos.app.name\\}", name)
                        .replaceAll("\\$\\{onos.app.origin\\}", origin)
                        .replaceAll("\\$\\{onos.app.requires\\}", requiredApps)
                        .replaceAll("\\$\\{onos.app.category\\}", category)
                        .replaceAll("\\$\\{onos.app.title\\}", title)
                        .replaceAll("\\$\\{onos.app.url\\}", url)
                        .replaceAll("\\$\\{project.groupId\\}", projectGroupId)
                        .replaceAll("\\$\\{project.artifactId\\}", projectArtifactId)
                        .replaceAll("\\$\\{project.version\\}", projectVersion)
                        .replaceAll("\\$\\{project.description\\}", readme);
    }

    // Recursively archives the specified directory into a given ZIP stream.
    private void zipDirectory(String root, File dir, ZipOutputStream zos)
            throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE];
        File[] files = dir.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                if (file.isDirectory()) {
                    String path = root + file.getName() + "/";
                    zos.putNextEntry(new ZipEntry(path));
                    zipDirectory(path, file, zos);
                    zos.closeEntry();
                } else {
                    FileInputStream fin = new FileInputStream(file);
                    zos.putNextEntry(new ZipEntry(root + file.getName()));
                    int length;
                    while ((length = fin.read(buffer)) > 0) {
                        zos.write(buffer, 0, length);
                    }
                    zos.closeEntry();
                    fin.close();
                }
            }
        }
    }
}