/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.marmotta.maven.plugins.refpack;

import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.*;
import org.apache.maven.project.*;
import org.jdom2.Element;
import org.jdom2.Text;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.sonatype.aether.RepositorySystem;
import org.sonatype.aether.RepositorySystemSession;
import org.sonatype.aether.artifact.Artifact;
import org.sonatype.aether.collection.CollectRequest;
import org.sonatype.aether.collection.DependencyCollectionException;
import org.sonatype.aether.graph.Dependency;
import org.sonatype.aether.graph.DependencyNode;
import org.sonatype.aether.repository.RemoteRepository;
import org.sonatype.aether.resolution.DependencyRequest;
import org.sonatype.aether.resolution.DependencyResolutionException;
import org.sonatype.aether.resolution.DependencyResult;
import org.sonatype.aether.util.artifact.DefaultArtifact;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Generate IzPack refpack descriptions from Maven dependencies
 */
@Mojo(name = "generate", defaultPhase = LifecyclePhase.VALIDATE, requiresDependencyResolution = ResolutionScope.COMPILE)
public class RefPackMojo extends AbstractMojo {
    
    /**
     * Location of the file.
     */
    @Parameter(property="project.build.directory", required = true)
    private File outputDirectory;

    @Parameter(property = "project", required = true, readonly = true)
    private MavenProject project;

    /**
     * The Group Identifier of the artifacts that should be considered local modules. When walking
     * the dependency tree, the process will break at each module of this group id and instead add
     * a dependency to the other module to the refpacks.
     */
    @Parameter(property="refpack.moduleGroupId", defaultValue="org.apache.marmotta", required = true)
    private String moduleGroupId;

    /**
     * The entry point to Aether, i.e. the component doing all the work.
     *
     */
    @Component
    private RepositorySystem repoSystem;

    @Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
    private RepositorySystemSession session;

    /**
     * The project's remote repositories to use for the resolution of project dependencies.
     */
    @Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true)
    private List<RemoteRepository> projectRepos;

    @Component
    private ProjectBuilder projectBuilder;

    @Component
    private ArtifactFactory artifactFactory;

    /**
     * The required modules of the refpack
     */
    @Parameter(property = "refpack.requiredModules")
    private List<String> requiredModules;

    // we collect here the library dependencies of each module, so we can identify which of the dependencies are already
    // covered by another module the current module depends on
    private HashMap<Artifact,Set<Artifact>> moduleLibraries;

    // and here we collect the module dependencies of each module
    private HashMap<Artifact,Set<Artifact>> moduleDependencies;

    public void execute() throws MojoExecutionException {
        moduleLibraries = new HashMap<Artifact, Set<Artifact>>();
        moduleDependencies = new HashMap<Artifact, Set<Artifact>>();

        getLog().info("generating reference packs for group id "+moduleGroupId);

        for(org.apache.maven.artifact.Artifact artifact : project.getArtifacts()) {
            if(artifact.getGroupId().equals(moduleGroupId)) {

                DefaultArtifact aetherArtifact = new DefaultArtifact(artifact.getGroupId(),artifact.getArtifactId(), artifact.getType(), artifact.getVersion());
                Dependency rootDependency = new Dependency(aetherArtifact, "runtime");

                try {
                    CollectRequest collectRequest = new CollectRequest();
                    collectRequest.setRoot(rootDependency);
                    collectRequest.setRepositories(projectRepos);

                    DependencyNode rootNode = repoSystem.collectDependencies( session, collectRequest ).getRoot();

                    DependencyRequest request = new DependencyRequest(rootNode,null);
                    DependencyResult result = repoSystem.resolveDependencies(session,request);


                    getLog().info("Artifact: " + aetherArtifact);
                    for(DependencyNode child : result.getRoot().getChildren()) {
                        if(child.getDependency().getArtifact().getGroupId().equals(moduleGroupId)) {
                            processModule(child);
                        }
                    }
                    processModule(result.getRoot());
                    /*
                    deps = aether.resolve(aetherArtifact, JavaScopes.RUNTIME);

                    getLog().info("Artifact: "+aetherArtifact);
                    for(Artifact dep : deps) {
                        getLog().info("- dependency "+dep.getFile().getAbsolutePath());
                    }
                    */
                } catch (DependencyResolutionException e) {
                    getLog().warn("could not resolve dependencies for artifact "+aetherArtifact,e);
                } catch (DependencyCollectionException e) {
                    getLog().warn("could not resolve dependencies for artifact "+aetherArtifact,e);
                }
            }

        }

    }

    /**
     * Collect the dependencies to other libraries that are not already collected by modules the current
     * module depends on.
     *
     * @param node
     * @param currentModule
     */
    private void collectLibraryDependencies(DependencyNode node, Artifact currentModule) {
		String groupId = node.getDependency().getArtifact().getGroupId();
        String artifactId = node.getDependency().getArtifact().getArtifactId();
        if(!isPackDependency(groupId, artifactId)) {
            // first check if the current artifact is already covered by a module the current module depends on
            for(Artifact dependentArtifact : moduleDependencies.get(currentModule)) {
                if(moduleLibraries.containsKey(dependentArtifact) &&
                        moduleLibraries.get(dependentArtifact).contains(node.getDependency().getArtifact())) {
                    return;
                }
            }

            // collect the current dependency for the module
            moduleLibraries.get(currentModule).add(node.getDependency().getArtifact());

            for(DependencyNode child : node.getChildren()) {
                collectLibraryDependencies(child, currentModule);
            }
        }
    }

    private boolean isPackDependency(String groupId, String artifactId) {
        // only marmotta group-id and artifacts starting with marmotta-
        return groupId.equals(moduleGroupId) && artifactId.startsWith("marmotta-")
                // but not the commons and the JS-client
                && !artifactId.equals("marmotta-commons") && !artifactId.equals("marmotta-client-js") 
                // and not the marmotta-sesame-tools
                && !artifactId.startsWith("marmotta-util-") && !artifactId.startsWith("marmotta-sail-")
                && !artifactId.startsWith("marmotta-rio-") && !artifactId.startsWith("marmotta-model-");
    }

    /**
     * Collect the dependencies to other modules inside the same project
     * @param node
     * @param currentModule
     */
    private void collectModuleDependencies(DependencyNode node, Artifact currentModule) {
		String groupId = node.getDependency().getArtifact().getGroupId();
        String artifactId = node.getDependency().getArtifact().getArtifactId();
		if(isPackDependency(groupId, artifactId)) {
            moduleDependencies.get(currentModule).add(node.getDependency().getArtifact());
        }
    }

    private void processModule(DependencyNode moduleNode) {
        CollectRequest collectRequest = new CollectRequest();
        collectRequest.setRoot(moduleNode.getDependency());
        collectRequest.setRepositories(projectRepos);
        try {
            // collect all the dependency graph for the module, and print it until we reach a dependency to a local module
            DependencyNode rootNode = repoSystem.collectDependencies( session, collectRequest ).getRoot();

            DependencyRequest request = new DependencyRequest(rootNode,null);
            DependencyResult result = repoSystem.resolveDependencies(session,request);

            // add entry to module dependencies
            moduleLibraries.put(moduleNode.getDependency().getArtifact(), new HashSet<Artifact>());
            moduleDependencies.put(moduleNode.getDependency().getArtifact(), new HashSet<Artifact>());

            getLog().info("processing module "+moduleNode.getDependency().getArtifact().getArtifactId()+":");
            for(DependencyNode child : result.getRoot().getChildren()) {
                collectModuleDependencies(child,moduleNode.getDependency().getArtifact());
            }
            for(DependencyNode child : result.getRoot().getChildren()) {
                collectLibraryDependencies(child, moduleNode.getDependency().getArtifact());
            }

            // information output
            /*
            for(Artifact otherModule : moduleDependencies.get(moduleNode.getDependency().getArtifact())) {
                getLog().info(" - depending on module "+otherModule.getArtifactId());
            }
            for(Artifact library : moduleLibraries.get(moduleNode.getDependency().getArtifact())) {
                getLog().info(" - depending on library "+library);
            }
            */

            File destination = new File(outputDirectory, moduleNode.getDependency().getArtifact().getArtifactId() + ".xml");
            if (!destination.getParentFile().exists()) { 
            	destination.getParentFile().mkdirs();
            }
        	if (!destination.exists()) {
        		destination.createNewFile();
        	}

            getLog().info("writing refpack to " + destination.getAbsolutePath());

            // write to output directory
            writeModuleXML(moduleNode.getDependency().getArtifact(), new FileOutputStream(destination));

        } catch (DependencyCollectionException e) {
            getLog().error("error while collecting dependencies for module " + moduleNode.getDependency().getArtifact(), e);
        } catch (DependencyResolutionException e) {
            getLog().error("error while resolving dependencies for module " + moduleNode.getDependency().getArtifact(), e);
        } catch (IOException e) {
            getLog().error("I/O error while writing refpack for module " + moduleNode.getDependency().getArtifact(), e);
        }

    }

    private void writeModuleXML(Artifact module, OutputStream out) throws IOException {
        Element installation = new Element("installation");
        installation.setAttribute("version","1.0");

        Element packs = new Element("packs");
        installation.addContent(packs);

        Element pack = new Element("pack");
        packs.addContent(pack);

        // get the model for the artifact, we read name and description from it

        Model pom = getArtifactModel(module);

        // set name of pack from artifact
        if(pom != null && pom.getName() != null) {
            pack.setAttribute("name",pom.getName());
        } else {
            pack.setAttribute("name",module.getArtifactId());
        }

        if(pom != null && pom.getDescription() != null) {
            Element description = new Element("description");
            description.setText(Text.normalizeString(pom.getDescription()));
            pack.addContent(description);
        }

        // add a file entry for the module itself
        if(!module.getExtension().equals("war")) {
            Element mainFile = new Element("file");
            pack.addContent(mainFile);
            mainFile.setAttribute("src",module.getFile().getAbsolutePath());
            mainFile.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/webapps/marmotta/WEB-INF/lib");
        }

        // add a file entry for each library of the artifact
        for(Artifact library : moduleLibraries.get(module)) {
            Element file = new Element("file");
            pack.addContent(file);
            file.setAttribute("src",library.getFile().getAbsolutePath());
            file.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/webapps/marmotta/WEB-INF/lib");
        }

        // add a depends name for each module the current one depends on  (in case the project is not the webapp)
        if(!module.getExtension().equals("war")) {
            if(requiredModules.contains(module.getArtifactId())) {
                pack.setAttribute("required","yes");
            } else {
                pack.setAttribute("required","no");
            }

            for(Artifact dependency : moduleDependencies.get(module)) {
                Element depends = new Element("depends");
                pack.addContent(depends);

                // get the model for the artifact, we read name and description from it
                Model pom2 = getArtifactModel(dependency);

                // set name of pack from artifact
                if(pom2 != null && pom2.getName() != null) {
                    depends.setAttribute("packname", pom2.getName());
                } else {
                    depends.setAttribute("packname",module.getArtifactId());
                }
            }
        } else {
            pack.setAttribute("required","yes");

            // add webapp directory from installer configuration
            Element appDir = new Element("fileset");
            appDir.setAttribute("dir",outputDirectory+"/../webapp/");
            appDir.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/webapps/marmotta/");
            appDir.setAttribute("includes","**");

            pack.addContent(appDir);

            Element logDir = new Element("fileset");
            logDir.setAttribute("dir",outputDirectory+"/../log/");

            logDir.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/logs/");
            logDir.setAttribute("includes","**");

            pack.addContent(logDir);
        }

        XMLOutputter writer = new XMLOutputter(Format.getPrettyFormat());
        writer.output(installation,out);

    }

    private Model getArtifactModel(Artifact artifact) {
        org.apache.maven.artifact.Artifact mavenArtifact = artifactFactory.createArtifact(artifact.getGroupId(),artifact.getArtifactId(),artifact.getVersion(),"runtime",artifact.getExtension());

        DefaultProjectBuildingRequest req = new DefaultProjectBuildingRequest();
        req.setRepositorySession(session);
        req.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_STRICT);

        try {
            ProjectBuildingResult res = projectBuilder.build(mavenArtifact, req);

            return res.getProject().getModel();
        } catch (ProjectBuildingException e) {
            getLog().warn("error building artifact model for artifact "+artifact,e);
            return null;
        }

    }
}
