/**
 * 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.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.execution.MavenSession;
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.apache.maven.repository.RepositorySystem;
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.sonatype.plexus.build.incremental.BuildContext;

/**
 * @description 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;
        
    @Component
    private MavenSession session;
    
    /**
     * Allows running in a separate process.
     */
    @Parameter(defaultValue = "false")
    private boolean fork;
    
    /**
     * 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();
                        } else {
                            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 {
        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].getBindingFile() != null) { 
                        URI bindingURI = mapLocation(xsdOptions[x].getBindingFile());
                        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 (int z = 0; z < files.length; ++z) {
                                if (files[z].lastModified() > doneFile.lastModified()) {
                                    doWork = true;
                                }
                            }
                        }
                    }

                    if (doWork) {
                        try {
                            File files[] = xsdOptions[x].getDependencies();
                            if (files != null) {
                                for (int z = 0; z < files.length; ++z) {
                                    if (files[z].lastModified() > doneFile.lastModified()) {
                                        buildContext.removeMessages(files[z]);
                                    }
                                }
                            }
                            removeMessages(xsdFile);
                            removeMessages(xsdOptions[x].getBindingFile());
                            int i = run(xsdOptions[x], xsdFile, outputDir);
                            if (i == 0) {
                                doneFile.delete();
                                doneFile.createNewFile();
                            }
                            File dirs[] = xsdOptions[x].getDeleteDirs();
                            if (dirs != null) {
                                for (int idx = 0; idx < dirs.length; ++idx) {
                                    result = result && deleteDir(dirs[idx]);
                                }
                            }
                            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 List<File> resolve(String artifactDescriptor) throws MojoExecutionException {
        String[] s = artifactDescriptor.split(":");

        String type = s.length >= 4 ? s[3] : "jar";
        Artifact artifact = repository.createArtifact(s[0], s[1], s[2], type);

        ArtifactResolutionRequest request = new ArtifactResolutionRequest();
        request.setArtifact(artifact);
        
        request.setResolveRoot(true).setResolveTransitively(true);
        request.setServers(session.getRequest().getServers());
        request.setMirrors(session.getRequest().getMirrors());
        request.setProxies(session.getRequest().getProxies());
        request.setLocalRepository(session.getLocalRepository());
        List<ArtifactRepository> r = new ArrayList<ArtifactRepository>();
        r.addAll(project.getPluginArtifactRepositories());
        r.addAll(project.getRemoteArtifactRepositories());
        r.addAll(session.getRequest().getRemoteRepositories());
        r.addAll(session.getRequest().getPluginArtifactRepositories());
        request.setRemoteRepositories(r);
        ArtifactResolutionResult result = repository.resolve(request);
        List<File> files = new ArrayList<File>();
        for (Artifact a : result.getArtifacts()) {
            if (a.getFile() == null) {
                throw new MojoExecutionException("Unable to resolve " + a.toString()
                        + " while resolving " + artifactDescriptor);
            }
            files.add(a.getFile());
        }
        if (!files.contains(artifact.getFile())) {
            files.add(artifact.getFile());
        }
        return files;
    }
    
    protected List<String> getClasspathElements() throws DependencyResolutionRequiredException {
        return project.getCompileClasspathElements();
    }
    
    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.size() > 0) {
            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[newCp.size()]),
                                                          Thread.currentThread().getContextClassLoader()));
        }
        if (option.getPackagename() != null) {
            list.add("-p");
            list.add(option.getPackagename());
        }
        if (option.getBindingFile() != null) {
            list.add("-b");
            list.add(mapLocation(option.getBindingFile()).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");            
        }

        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[list.size()]);
        
    }
    
    private boolean deleteDir(File f) {
        if (f.isDirectory()) {
            File files[] = f.listFiles();
            for (int idx = 0; idx < files.length; ++idx) {
                deleteDir(files[idx]);
            }
        }
        
        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);
        
        
        File file = null;
        try {
            //file = new File("Y:\\Users\\dkulp\\tmp\\test.jar");
            file = File.createTempFile("cxf-xjc-plugin", ".jar");
            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;
    }
    
}
