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

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
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.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.archiver.jar.JarArchiver;
import org.codehaus.plexus.archiver.jar.Manifest;
import org.codehaus.plexus.archiver.jar.Manifest.Attribute;
import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.util.cli.CommandLineUtils;
import org.codehaus.plexus.util.cli.Commandline;
import org.codehaus.plexus.util.cli.StreamConsumer;
import org.eclipse.aether.RepositoryException;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.DependencyRequest;
import org.sonatype.plexus.build.incremental.BuildContext;

/**
 * CXF XSD To Java Tool
 */
public abstract class AbstractXSDToJavaMojo extends AbstractMojo {
    @Component
    protected MavenProject project;
    
    @Parameter
    XsdOption[] xsdOptions;
    
    /**
     * Directory in which the "DONE" markers are saved that 
     */
    @Parameter(defaultValue = "${project.build.directory}/cxf-xsd-plugin-markers",
        property = "cxf.markerDirectory")
    File markerDirectory;
    
    /**
     * The extension artifacts that will be retrieved and added to the classpath.
     */
    @Parameter
    private List<String> extensions;
    
       
    @Component 
    private BuildContext buildContext;

    @Component
    private RepositorySystem repository;

    /**
     * The current repository/network configuration of Maven.
     */
    @Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
    private RepositorySystemSession repoSession;

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

    /**
     * Allows running in a separate process.
     */
    @Parameter(defaultValue = "false")
    private boolean fork;
    
    /**
     * 
     */
    @Parameter(defaultValue = "${project.build.sourceEncoding}")
    private String encoding;
    
    /**
     * Sets the Java executable to use when fork parameter is <code>true</code>.
     */
    @Parameter(defaultValue = "${java.home}/bin/java")
    private String javaExecutable;
    
    
    /**
     * Sets the JVM arguments (i.e. <code>-Xms128m -Xmx128m</code>) if fork is set to <code>true</code>.
     */
    @Parameter(property = "cxf.xjc.jvmArgs")
    private String additionalJvmArgs;
    
    /**
     * The plugin dependencies, needed for the fork mode.
     */
    @Parameter(property = "plugin.artifacts", readonly = true, required = true)
    private List<Artifact> pluginArtifacts;    

    abstract String getOutputDir();
    
    
    
    private URI mapLocation(String s) throws MojoExecutionException {
        try {
            File file = new File(s).getAbsoluteFile();
            URI uri;
            if (file.exists()) {
                uri = file.toURI();
            } else {
                file = new File(project.getBasedir(), s).getAbsoluteFile();
                if (file.exists()) {
                    uri = file.toURI();
                } else {
                    try {
                        uri = new URI(s);
                    } catch (URISyntaxException use) {
                        file = new File(s).getAbsoluteFile();
                        if (file.getParentFile().exists()) {
                            return file.toURI();
                        }
                        throw use;
                    }
                }
            }
            if ("classpath".equals(uri.getScheme())) {
                URL url = Thread.currentThread().getContextClassLoader()
                    .getResource(s.substring(10));
                if (url == null) {
                    url = Thread.currentThread().getContextClassLoader()
                        .getResource(s.substring(11));
                }
                if (url != null) {
                    uri = url.toURI();
                }
            }
            return uri;
        } catch (URISyntaxException e1) {
            throw new MojoExecutionException("Could not map " + s, e1);
        }
    }
    public void execute() throws MojoExecutionException {
        if (isJava9Compatible()) {
            fork = true;
            additionalJvmArgs =  
                     "--add-exports=jdk.xml.dom/org.w3c.dom.html=ALL-UNNAMED "
                    + "--add-exports=java.xml/com.sun.org.apache.xerces.internal.impl.xs=ALL-UNNAMED "
                    + "--add-opens java.base/java.security=ALL-UNNAMED "
                    + "--add-opens java.base/java.net=ALL-UNNAMED "
                    + "--add-opens java.base/java.lang=ALL-UNNAMED "
                    + "--add-opens java.base/java.util=ALL-UNNAMED "
                    + "--add-opens java.base/java.util.concurrent=ALL-UNNAMED " 
                    + (additionalJvmArgs == null ? "" : additionalJvmArgs); 
        }
        String outputDir = getOutputDir();
        
        File outputDirFile = new File(outputDir);
        outputDirFile.mkdirs();
        markerDirectory.mkdirs();

        boolean result = true;
        
        if (xsdOptions == null) {
            throw new MojoExecutionException("Must specify xsdOptions");           
        }
    
        for (int x = 0; x < xsdOptions.length; x++) {
            ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
            final String[] xsdFiles = getXsdFiles(xsdOptions[x].getXsdDir(), xsdOptions[x].getXsd());
            for (String xsdFile : xsdFiles) {
                try {
                    URI xsdURI = mapLocation(xsdFile);
                    URI basedir = project.getBasedir().toURI();

                    String doneFileName = xsdURI.toString();
                    if (doneFileName.startsWith(basedir.toString())) {
                        doneFileName = doneFileName.substring(basedir.toString().length());
                    }

                    doneFileName = doneFileName.replace('?', '_')
                        .replace('&', '_').replace('/', '_').replace('\\', '_')
                        .replace(':', '_').replace('!', '_');

                    // If URL to WSDL, replace ? and & since they're invalid chars for file names
                    File doneFile =
                        new File(markerDirectory, "." + doneFileName + ".DONE");

                    long srctimestamp = 0;
                    if ("file".equals(xsdURI.getScheme())) {
                        srctimestamp = new File(xsdURI).lastModified();
                    } else {
                        try {
                            srctimestamp = xsdURI.toURL().openConnection().getDate();
                        } catch (Exception e) {
                            //ignore
                        }
                    }
                    if (xsdOptions[x].getBindingFiles() != null) {
                        for (String bf : xsdOptions[x].getBindingFiles()) {
                            URI bindingURI = mapLocation(bf);
                            if ("file".equals(bindingURI.getScheme())) {
                                long bts = new File(bindingURI).lastModified();
                                if (bts > srctimestamp) {
                                    srctimestamp = bts;
                                }
                            }
                        }
                    }

                    boolean doWork = false;
                    if (!doneFile.exists()) {
                        doWork = true;
                    } else if (srctimestamp > doneFile.lastModified()) {
                        doWork = true;
                    } else {
                        File[] files = xsdOptions[x].getDependencies();
                        if (files != null) {
                            for (File file : files) {
                                if (file.lastModified() > doneFile.lastModified()) {
                                    doWork = true;
                                }
                            }
                        }
                    }

                    if (doWork) {
                        try {
                            File[] files = xsdOptions[x].getDependencies();
                            if (files != null) {
                                for (File file : files) {
                                    if (file.lastModified() > doneFile.lastModified()) {
                                        buildContext.removeMessages(file);
                                    }
                                }
                            }
                            removeMessages(xsdFile);
                            if (xsdOptions[x].getBindingFiles() != null) {
                                for (String bf : xsdOptions[x].getBindingFiles()) {
                                    removeMessages(bf);
                                }
                            }
                            int i = run(xsdOptions[x], xsdFile, outputDir);
                            if (i == 0) {
                                doneFile.delete();
                                doneFile.createNewFile();
                            }
                            File[] dirs = xsdOptions[x].getDeleteDirs();
                            if (dirs != null) {
                                for (File dir : dirs) {
                                    result = result && deleteDir(dir);
                                }
                            }
                            buildContext.refresh(outputDirFile);
                        } catch (Exception e) {
                            throw new MojoExecutionException(e.getMessage(), e);
                        }
                    }

                    if (!result) {
                        throw new MojoExecutionException("Could not delete redundant dirs");
                    }
                } finally {
                    Thread.currentThread().setContextClassLoader(origLoader);
                }
            }
        }
    }
    
    private String[] getXsdFiles(String xsdDir, String xsd) throws MojoExecutionException {
        final String[] xsdFiles;
        if (xsdDir != null && !xsdDir.isEmpty()) {
            File dir = new File(xsdDir);
            if (!dir.isDirectory()) {
                throw new MojoExecutionException("Error, xsdDir \"" + xsdDir + "\" does not exist.");
            }  
            String[] fileList = dir.list(new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    return name.endsWith(".xsd");
                }
            });
            if (fileList == null || fileList.length == 0) {
                throw new MojoExecutionException("Error, xsdDir \"" + xsdDir + "\" does not contain any *.xsd files.");
            }
            xsdFiles = new String[fileList.length];
            for (int i = 0; i < fileList.length; ++i) {
                xsdFiles[i] = xsdDir + (xsdDir.endsWith(File.separator) ? "" : File.separator) + fileList[i];
            }
        } else {
            xsdFiles = new String[1];
            xsdFiles[0] = xsd;
        }
        return xsdFiles;
    }

    private Set<File> resolve(String artifactDescriptor) throws MojoExecutionException, RepositoryException {
        final Set<File> files = new HashSet<File>();
        for (ArtifactResult artifactResult : repository
                .resolveDependencies(repoSession,
                        new DependencyRequest(new CollectRequest(
                                new Dependency(new DefaultArtifact(artifactDescriptor), null), remoteRepos), null))
                .getArtifactResults()) {
            final org.eclipse.aether.artifact.Artifact artifact = artifactResult.getArtifact();
            if (null == artifact || null == artifact.getFile()) {
                throw new MojoExecutionException("Unable to resolve " + artifact
                        + " while resolving " + artifactDescriptor);
            }
            files.add(artifact.getFile());
        }
        return files;
    }

    protected List<String> getClasspathElements() throws DependencyResolutionRequiredException {
        return project.getCompileClasspathElements();
    }

    protected boolean isJava9Compatible() {
        String version = System.getProperty("java.specification.version");
        int majorVersion;
        if (version.contains(".")) { //before jdk 9
            majorVersion = Integer.parseInt(version.split("\\.")[1]);
        } else {
            majorVersion = Integer.parseInt(version);
        }
        
        return majorVersion >= 9;
    }
    
    private int run(XsdOption option, String xsdFile, String outputDir) throws Exception {
        if (!fork) {
            String[] args = getArguments(option, outputDir);
            this.getLog().debug("Args: " + Arrays.asList(args));
            XJCErrorListener listener = new XJCErrorListener(buildContext);
            int i = new XSDToJavaRunner(args, listener, new File(xsdFile), getClasspathElements()).run();
            if (i != 0 && listener.getFirstError() != null) {
                throw listener.getFirstError();
            }
            return i;
        }
        return runForked(option, outputDir);
    }
    
    private void removeMessages(String file) throws MojoExecutionException {
        if (file == null) {
            return;
        }
        URI location = mapLocation(file);
        if ("file".equals(location.getScheme())) {
            File f = new File(location);
            if (f.exists()) {
                buildContext.removeMessages(f);
            }
        }        
    }
    private String[] getArguments(XsdOption option, String outputDir) 
        throws MojoExecutionException, MalformedURLException {
        
        List<URL> newCp = new ArrayList<URL>();
        List<String> list = new ArrayList<String>();
        if (extensions != null && !extensions.isEmpty()) {
            try {
                for (String ext : extensions) {
                    for (File file : resolve(ext)) {
                        list.add("-classpath");
                        list.add(file.toURI().toURL().toExternalForm());
                        newCp.add(file.toURI().toURL());
                    }
                }
            } catch (Exception ex) {
                throw new MojoExecutionException("Could not download extension artifact", ex);
            }
        }
        if (!newCp.isEmpty()) {
            Thread.currentThread()
                .setContextClassLoader(new URLClassLoader(newCp.toArray(new URL[0]),
                                                          Thread.currentThread().getContextClassLoader()));
        }
        if (option.getPackagename() != null) {
            list.add("-p");
            list.add(option.getPackagename());
        }
        if (option.getBindingFiles() != null) {
            for (String bf : option.getBindingFiles()) {
                list.add("-b");
                list.add(mapLocation(bf).toString());
            }
        }
        if (option.getCatalog() != null) {
            list.add("-catalog");
            list.add(option.getCatalog());
        }
        if (option.isExtension()) {
            list.add("-extension");
        }
        if (option.getExtensionArgs() != null) {
            list.addAll(option.getExtensionArgs());
        }          
        if (getLog().isDebugEnabled()) {
            list.add("-verbose");            
        }
        if (encoding != null) {
            list.add("-encoding");
            list.add(encoding);
        }
        
        String[] xsdFiles = getXsdFiles(option.getXsdDir(), option.getXsd());
        for (String xsdFile : xsdFiles) {
            list.add("-d");
            list.add(outputDir);
            list.add(mapLocation(xsdFile).toString());
        }

        return list.toArray(new String[0]);
        
    }
    
    private boolean deleteDir(File f) {
        if (f.isDirectory()) {
            File[] files = f.listFiles();
            for (File file : files) {
                deleteDir(file);
            }
        }
        
        if (f.exists()) {
            return f.delete();
        }
        
        return true;
    }
    private File getJavaExecutable() throws IOException {
        String exe = isWindows() && !javaExecutable.endsWith(".exe") ? ".exe" : "";
        File javaExe = new File(javaExecutable + exe);

        if (!javaExe.isFile()) {
            throw new IOException(
                                  "The java executable '"
                                      + javaExe
                                      + "' doesn't exist or is not a file. " 
                                      + "Verify the <javaExecutable/> parameter.");
        }
        return javaExe;
    }
    private boolean isWindows() {
        String osName = System.getProperty("os.name");
        if (osName == null) {
            return false;
        }
        return osName.startsWith("Windows");
    }
    
    private int runForked(XsdOption option, String outputDir) throws Exception {
        String[] args = getArguments(option, outputDir);
        Commandline cmd = new Commandline();
        cmd.getShell().setQuotedArgumentsEnabled(true); // for JVM args
        cmd.setWorkingDirectory(project.getBuild().getDirectory());
        try {
            cmd.setExecutable(getJavaExecutable().getAbsolutePath());
        } catch (IOException e) {
            getLog().debug(e);
            throw new MojoExecutionException(e.getMessage(), e);
        }
        cmd.createArg().setLine(additionalJvmArgs);

        final File file;
        try {
            file = Files.createTempFile("cxf-xjc-plugin", ".jar").toFile();
            file.deleteOnExit();
            
            JarArchiver jar = new JarArchiver();
            jar.setDestFile(file.getAbsoluteFile());

            Manifest manifest = new Manifest();
            Attribute attr = new Attribute();
            attr.setName("Class-Path");
            StringBuilder b = new StringBuilder(8000);
            for (String cp : getClasspathElements()) {
                URI uri = mapLocation(cp);
                if (uri != null) {
                    b.append(uri.toString()).append(' ');
                }
            }
            for (Artifact a : pluginArtifacts) {
                b.append(a.getFile().toURI().toURL().toExternalForm()).append(' ');
            }
            attr.setValue(b.toString());
            manifest.getMainSection().addConfiguredAttribute(attr);

            attr = new Attribute();
            attr.setName("Main-Class");
            attr.setValue(XSDToJavaRunner.class.getName());
            manifest.getMainSection().addConfiguredAttribute(attr);

            if (getLog().isDebugEnabled()) {
                getLog().debug("Manifest: " + manifest);
            }
            
            jar.addConfiguredManifest(manifest);
            jar.createArchive();

            cmd.createArg().setValue("-jar");
            
            String tmpFilePath = file.getAbsolutePath();
            if (tmpFilePath.contains(" ")) {
                //ensure the path is in double quotation marks if the path contain space
                tmpFilePath = "\"" + tmpFilePath + "\"";
            }
            cmd.createArg().setValue(tmpFilePath);

        } catch (Exception e1) {
            throw new MojoExecutionException("Could not create runtime jar", e1);
        }
        cmd.addArguments(args);

        StreamConsumer out = new StreamConsumer() {
            File file;
            int severity;
            int linenum;
            int column;
            StringBuilder message = new StringBuilder();
            
            public void consumeLine(String line) {
                if (getLog().isDebugEnabled()) {
                    getLog().debug(line);
                }
                if (line.startsWith("DONE")) {
                    buildContext.addMessage(file, linenum, column, message.toString(), severity, null);
                } else if (line.startsWith("MSG: ")
                    || line.startsWith("ERROR: ")
                    || line.startsWith("WARNING: ")) {
                    file = new File(line.substring(line.indexOf(' ')).trim());
                    String type = line.substring(0, line.indexOf(':'));
                    if (type.contains("ERROR")) {
                        severity = BuildContext.SEVERITY_ERROR;
                    } else if (type.contains("WARNING")) {
                        severity = BuildContext.SEVERITY_WARNING;
                    } else {
                        severity = 0;
                    }
                    linenum = 0;
                    column = 0;
                    message.setLength(0);
                } else if (line.startsWith("Col: ")) {
                    column = Integer.parseInt(line.substring(line.indexOf(' ')).trim());
                } else if (line.startsWith("Line: ")) {
                    linenum = Integer.parseInt(line.substring(line.indexOf(' ')).trim());
                } else if (line.startsWith("Severity: ")) {
                    severity = Integer.parseInt(line.substring(line.indexOf(' ')).trim());
                } else {
                    message.append(line).append('\n');
                }
            }
        };
        int exitCode;
        try {
            exitCode = CommandLineUtils.executeCommandLine(cmd, out, out);
        } catch (CommandLineException e) {
            getLog().debug(e);
            throw new MojoExecutionException(e.getMessage(), e);
        }
        

        String cmdLine = CommandLineUtils.toString(cmd.getCommandline());

        if (exitCode != 0) {
            StringBuffer msg = new StringBuffer("\nExit code: ");
            msg.append(exitCode);
            msg.append('\n');
            msg.append("Command line was: ").append(cmdLine).append('\n').append('\n');

            throw new MojoExecutionException(msg.toString());
        }

        file.delete();
        return 0;
    }
    
}
