package org.apache.tomcat.maven.plugin.tomcat8.run;
/*
 * 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.
 */

import org.apache.catalina.Context;
import org.apache.catalina.WebResource;
import org.apache.catalina.WebResourceSet;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.webresources.EmptyResource;
import org.apache.catalina.webresources.FileResource;
import org.apache.catalina.webresources.FileResourceSet;
import org.apache.catalina.webresources.JarResource;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
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.plugins.annotations.ResolutionScope;
import org.apache.maven.shared.filtering.MavenFileFilterRequest;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.tomcat.maven.common.run.ClassLoaderEntriesCalculator;
import org.apache.tomcat.maven.common.run.ClassLoaderEntriesCalculatorRequest;
import org.apache.tomcat.maven.common.run.ClassLoaderEntriesCalculatorResult;
import org.apache.tomcat.maven.common.run.TomcatRunException;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.Xpp3DomWriter;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
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.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * Runs the current project as a dynamic web application using an embedded Tomcat server.
 *
 * @author Olivier Lamy
 * @since 2.0
 */
@Mojo( name = "run", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true )
@Execute( phase = LifecyclePhase.PROCESS_CLASSES )
public class RunMojo
    extends AbstractRunMojo
{
    // ----------------------------------------------------------------------
    // Mojo Parameters
    // ----------------------------------------------------------------------


    /**
     * The set of dependencies for the web application being run.
     */
    @Parameter( defaultValue = "${project.artifacts}", required = true, readonly = true )
    private Set<Artifact> dependencies;

    /**
     * The web resources directory for the web application being run.
     */
    @Parameter( defaultValue = "${basedir}/src/main/webapp", property = "tomcat.warSourceDirectory" )
    private File warSourceDirectory;


    /**
     * Set the "follow standard delegation model" flag used to configure our ClassLoader.
     *
     * @see http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/loader/WebappLoader.html#setDelegate(boolean)
     * @since 1.0
     */
    @Parameter( property = "tomcat.delegate", defaultValue = "true" )
    private boolean delegate = true;

    /**
     * @since 2.0
     */
    @Component
    private ClassLoaderEntriesCalculator classLoaderEntriesCalculator;

    /**
     * will add /WEB-INF/lib/*.jar and /WEB-INF/classes from war dependencies in the webappclassloader
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.addWarDependenciesInClassloader", defaultValue = "true" )
    private boolean addWarDependenciesInClassloader;

    /**
     * will use the test classpath rather than the compile one and will add test dependencies too
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.useTestClasspath", defaultValue = "false" )
    private boolean useTestClasspath;

    /**
     * Additional optional directories to add to the embedded tomcat classpath.
     *
     * @since 2.0
     */
    @Parameter( alias = "additionalClassesDirs" )
    private List<String> additionalClasspathDirs;


    public final File getWarSourceDirectory()
    {
        return warSourceDirectory;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected File getDocBase()
        throws IOException
    {
        // https://issues.apache.org/jira/browse/MTOMCAT-239
        // when running a jar docBase doesn't exists so create a fake one
        if ( !warSourceDirectory.exists() )
        {
            // we create a temporary file in build.directory
            final File tempDocBase = createTempDirectory( new File( project.getBuild().getDirectory() ) );
            Runtime.getRuntime().addShutdownHook( new Thread()
            {
                @Override
                public void run()
                {
                    try
                    {
                        FileUtils.deleteDirectory( tempDocBase );
                    }
                    catch ( Exception e )
                    {
                        // we can consider as safe to ignore as it's located in build directory
                    }
                }
            } );
            return tempDocBase;
        }
        return warSourceDirectory;
    }

    private static File createTempDirectory( File baseTmpDirectory )
        throws IOException
    {
        final File temp = File.createTempFile( "temp", Long.toString( System.nanoTime() ), baseTmpDirectory );

        if ( !( temp.delete() ) )
        {
            throw new IOException( "Could not delete temp file: " + temp.getAbsolutePath() );
        }

        if ( !( temp.mkdir() ) )
        {
            throw new IOException( "Could not create temp directory: " + temp.getAbsolutePath() );
        }

        return temp;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected File getContextFile()
        throws MojoExecutionException
    {
        File temporaryContextFile = null;

        //----------------------------------------------------------------------------
        // context attributes backgroundProcessorDelay reloadable cannot be modified at runtime.
        // It looks only values from the file are used
        // so here we create a temporary file with values modified
        //----------------------------------------------------------------------------
        FileReader fr = null;
        FileWriter fw = null;
        StringWriter sw = new StringWriter();
        try
        {
            temporaryContextFile = File.createTempFile( "tomcat-maven-plugin", "temp-ctx-file" );
            temporaryContextFile.deleteOnExit();

            // format to modify/create <Context backgroundProcessorDelay="5" reloadable="false">
            if ( contextFile != null && contextFile.exists() )
            {
                MavenFileFilterRequest mavenFileFilterRequest = new MavenFileFilterRequest();
                mavenFileFilterRequest.setFrom( contextFile );
                mavenFileFilterRequest.setTo( temporaryContextFile );
                mavenFileFilterRequest.setMavenProject( project );
                mavenFileFilterRequest.setMavenSession( session );
                mavenFileFilterRequest.setFiltering( true );

                mavenFileFilter.copyFile( mavenFileFilterRequest );

                fr = new FileReader( temporaryContextFile );
                Xpp3Dom xpp3Dom = Xpp3DomBuilder.build( fr );
                xpp3Dom.setAttribute( "backgroundProcessorDelay", Integer.toString( backgroundProcessorDelay ) );
                xpp3Dom.setAttribute( "reloadable", Boolean.toString( isContextReloadable() ) );
                fw = new FileWriter( temporaryContextFile );
                Xpp3DomWriter.write( fw, xpp3Dom );
                Xpp3DomWriter.write( sw, xpp3Dom );
                getLog().debug( " generated context file " + sw.toString() );
            }
            else
            {
                if ( contextReloadable )
                {
                    // don't care about using a complicated xml api to create one xml line :-)
                    StringBuilder sb = new StringBuilder( "<Context " ).append( "backgroundProcessorDelay=\"" ).append(
                        Integer.toString( backgroundProcessorDelay ) ).append( "\"" ).append(
                        " reloadable=\"" + Boolean.toString( isContextReloadable() ) + "\"/>" );

                    getLog().debug( " generated context file " + sb.toString() );
                    fw = new FileWriter( temporaryContextFile );
                    fw.write( sb.toString() );
                }
                else
                {
                    // no user context file and contextReloadable false so no need about creating a hack one
                    return null;
                }
            }
        }
        catch ( IOException e )
        {
            getLog().error( "error creating fake context.xml : " + e.getMessage(), e );
            throw new MojoExecutionException( "error creating fake context.xml : " + e.getMessage(), e );
        }
        catch ( XmlPullParserException e )
        {
            getLog().error( "error creating fake context.xml : " + e.getMessage(), e );
            throw new MojoExecutionException( "error creating fake context.xml : " + e.getMessage(), e );
        }
        catch ( MavenFilteringException e )
        {
            getLog().error( "error filtering context.xml : " + e.getMessage(), e );
            throw new MojoExecutionException( "error filtering context.xml : " + e.getMessage(), e );
        }
        finally
        {
            IOUtil.close( fw );
            IOUtil.close( fr );
            IOUtil.close( sw );
        }

        return temporaryContextFile;
    }

    /**
     * {@inheritDoc}
     *
     * @throws MojoExecutionException
     */
    @Override
    protected WebappLoader createWebappLoader()
        throws IOException, MojoExecutionException
    {
        WebappLoader loader = super.createWebappLoader();

        if ( useSeparateTomcatClassLoader )
        {
            loader.setDelegate( delegate );
        }

        return loader;
    }

    @Override
    protected void enhanceContext( final Context context )
        throws MojoExecutionException
    {
        super.enhanceContext( context );

        try
        {
            ClassLoaderEntriesCalculatorRequest request = new ClassLoaderEntriesCalculatorRequest() //
                .setDependencies( dependencies ) //
                .setLog( getLog() ) //
                .setMavenProject( project ) //
                .setAddWarDependenciesInClassloader( addWarDependenciesInClassloader ) //
                .setUseTestClassPath( useTestClasspath );
            final ClassLoaderEntriesCalculatorResult classLoaderEntriesCalculatorResult =
                classLoaderEntriesCalculator.calculateClassPathEntries( request );
            final List<String> classLoaderEntries = classLoaderEntriesCalculatorResult.getClassPathEntries();
            final List<File> tmpDirectories = classLoaderEntriesCalculatorResult.getTmpDirectories();

            final List<String> jarPaths = extractJars( classLoaderEntries );

            List<URL> urls = new ArrayList<URL>( jarPaths.size() );

            for ( String jarPath : jarPaths )
            {
                try
                {
                    urls.add( new File( jarPath ).toURI().toURL() );
                }
                catch ( MalformedURLException e )
                {
                    throw new MojoExecutionException( e.getMessage(), e );
                }
            }

            getLog().debug( "classLoaderEntriesCalculator urls: " + urls );

            final URLClassLoader urlClassLoader = new URLClassLoader( urls.toArray( new URL[urls.size()] ) );

            final ClassRealm pluginRealm = getTomcatClassLoader();

            context.setResources(
                new MyDirContext( new File( project.getBuild().getOutputDirectory() ).getAbsolutePath(), //
                                  getPath(), //
                                  getLog() )
                {
                    @Override
                    public WebResource getClassLoaderResource( String path )
                    {
                        log.debug( "RunMojo#getClassLoaderResource: " + path );
                        URL url = urlClassLoader.getResource( StringUtils.removeStart( path, "/" ) );
                        // search in parent (plugin) classloader
                        if ( url == null )
                        {
                            url = pluginRealm.getResource( StringUtils.removeStart( path, "/" ) );
                        }

                        if (url == null)
                        {
                            // try in reactors
                            List<WebResource> webResources = findResourcesInDirectories( path, //
                                                                                         classLoaderEntriesCalculatorResult.getBuildDirectories() );

                            // so we return the first one
                            if ( !webResources.isEmpty() )
                            {
                                return webResources.get( 0 );
                            }
                        }



                        if ( url == null )
                        {
                            return new EmptyResource( this, getPath() );
                        }

                        return urlToWebResource( url, path );
                    }

                    @Override
                    public WebResource getResource( String path )
                    {
                        log.debug( "RunMojo#getResource: " + path );
                        return super.getResource( path );
                    }

                    @Override
                    public WebResource[] getResources( String path )
                    {
                        log.debug( "RunMojo#getResources: " + path );
                        return super.getResources( path );
                    }

                    @Override
                    protected WebResource[] getResourcesInternal( String path, boolean useClassLoaderResources )
                    {
                        log.debug( "RunMojo#getResourcesInternal: " + path );
                        return super.getResourcesInternal( path, useClassLoaderResources );
                    }

                    @Override
                    public WebResource[] getClassLoaderResources( String path )
                    {
                        try
                        {
                            Enumeration<URL> enumeration =
                                urlClassLoader.findResources( StringUtils.removeStart( path, "/" ) );
                            List<URL> urlsFound = new ArrayList<URL>();
                            List<WebResource> webResources = new ArrayList<WebResource>();
                            while ( enumeration.hasMoreElements() )
                            {
                                URL url = enumeration.nextElement();
                                urlsFound.add( url );
                                webResources.add( urlToWebResource( url, path ) );
                            }
                            log.debug(
                                "RunMojo#getClassLoaderResources: " + path + " found : " + urlsFound.toString() );

                            webResources.addAll( findResourcesInDirectories( path,
                                                                             classLoaderEntriesCalculatorResult.getBuildDirectories() ) );

                            return webResources.toArray( new WebResource[webResources.size()] );

                        }
                        catch ( IOException e )
                        {
                            throw new RuntimeException( e.getMessage(), e );
                        }
                    }


                    private List<WebResource> findResourcesInDirectories( String path, List<String> directories )
                    {
                        try
                        {
                            List<WebResource> webResources = new ArrayList<WebResource>();

                            for ( String directory : directories )
                            {

                                File file = new File( directory, path );
                                if ( file.exists() )
                                {
                                    webResources.add( urlToWebResource( file.toURI().toURL(), path ) );
                                }

                            }

                            return webResources;
                        }
                        catch ( MalformedURLException e )
                        {
                            throw new RuntimeException( e.getMessage(), e );
                        }
                    }


                    private WebResource urlToWebResource( URL url, String path )
                    {
                        JarFile jarFile = null;

                        try
                        {
                            // url.getFile is
                            // file:/Users/olamy/mvn-repo/org/springframework/spring-web/4.0.0.RELEASE/spring-web-4.0.0.RELEASE.jar!/org/springframework/web/context/ContextLoaderListener.class

                            int idx = url.getFile().indexOf( '!' );

                            if ( idx >= 0 )
                            {
                                String filePath = StringUtils.removeStart( url.getFile().substring( 0, idx ), "file:" );

                                jarFile = new JarFile( filePath );

                                JarEntry jarEntry = jarFile.getJarEntry( StringUtils.removeStart( path, "/" ) );

                                return new JarResource( this, //
                                                        getPath(), //
                                                        filePath, //
                                                        url.getPath().substring( 0, idx ), //
                                                        jarEntry, //
                                                        "", //
                                                        null );
                            }
                            else
                            {
                                return new FileResource( this, webAppPath, new File( url.getFile() ), true );
                            }

                        }
                        catch ( IOException e )
                        {
                            throw new RuntimeException( e.getMessage(), e );
                        }
                        finally
                        {
                            IOUtils.closeQuietly( jarFile );
                        }
                    }


                } );

            Runtime.getRuntime().addShutdownHook( new Thread()
            {
                @Override
                public void run()
                {
                    for ( File tmpDir : tmpDirectories )
                    {
                        try
                        {
                            FileUtils.deleteDirectory( tmpDir );
                        }
                        catch ( IOException e )
                        {
                            // ignore
                        }
                    }
                }
            } );

            if ( classLoaderEntries != null )
            {
                WebResourceSet webResourceSet = new FileResourceSet()
                {
                    @Override
                    public WebResource getResource( String path )
                    {

                        if ( StringUtils.startsWithIgnoreCase( path, "/WEB-INF/LIB" ) )
                        {
                            File file = new File( StringUtils.removeStartIgnoreCase( path, "/WEB-INF/LIB" ) );
                            return new FileResource( context.getResources(), getPath(), file, true );
                        }
                        if ( StringUtils.equalsIgnoreCase( path, "/WEB-INF/classes" ) )
                        {
                            return new FileResource( context.getResources(), getPath(),
                                                     new File( project.getBuild().getOutputDirectory() ), true );
                        }

                        File file = new File( project.getBuild().getOutputDirectory(), path );
                        if ( file.exists() )
                        {
                            return new FileResource( context.getResources(), getPath(), file, true );
                        }

                        //if ( StringUtils.endsWith( path, ".class" ) )
                        {
                            // so we search the class file in the jars
                            for ( String jarPath : jarPaths )
                            {
                                File jar = new File( jarPath );
                                if ( !jar.exists() )
                                {
                                    continue;
                                }

                                try
                                {
                                    JarFile jarFile = new JarFile( jar );
                                    JarEntry jarEntry =
                                        (JarEntry) jarFile.getEntry( StringUtils.removeStart( path, "/" ) );
                                    if ( jarEntry != null )
                                    {
                                        return new JarResource( context.getResources(), //
                                                                getPath(),  //
                                                                jarFile.getName(), //
                                                                jar.toURI().toString(), //
                                                                jarEntry, //
                                                                path, //
                                                                jarFile.getManifest() );
                                    }
                                }
                                catch ( IOException e )
                                {
                                    getLog().debug( "skip error building jar file: " + e.getMessage(), e );
                                }

                            }
                        }

                        return new EmptyResource( null, path );
                    }

                    @Override
                    public String[] list( String path )
                    {
                        if ( StringUtils.startsWithIgnoreCase( path, "/WEB-INF/LIB" ) )
                        {
                            return jarPaths.toArray( new String[jarPaths.size()] );
                        }
                        if ( StringUtils.equalsIgnoreCase( path, "/WEB-INF/classes" ) )
                        {
                            return new String[]{ new File( project.getBuild().getOutputDirectory() ).getPath() };
                        }
                        return super.list( path );
                    }

                    @Override
                    public Set<String> listWebAppPaths( String path )
                    {

                        if ( StringUtils.equalsIgnoreCase( "/WEB-INF/lib/", path ) )
                        {
                            // adding outputDirectory as well?
                            return new HashSet<String>( jarPaths );
                        }

                        File filePath = new File( getWarSourceDirectory(), path );

                        if ( filePath.isDirectory() )
                        {
                            Set<String> paths = new HashSet<String>();

                            String[] files = filePath.list();
                            if ( files == null )
                            {
                                return paths;
                            }

                            for ( String file : files )
                            {
                                paths.add( file );
                            }

                            return paths;

                        }
                        else
                        {
                            return Collections.emptySet();
                        }
                    }

                    @Override
                    public boolean mkdir( String path )
                    {
                        return super.mkdir( path );
                    }

                    @Override
                    public boolean write( String path, InputStream is, boolean overwrite )
                    {
                        return super.write( path, is, overwrite );
                    }

                    @Override
                    protected void checkType( File file )
                    {
                        //super.checkType( file );
                    }


                };

                context.getResources().addJarResources( webResourceSet );
            }

        }
        catch ( TomcatRunException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }

    }


    /**
     * extract List of path which are files (removing directories from the initial list)
     *
     * @param classLoaderEntries
     * @return
     */
    private List<String> extractJars( List<String> classLoaderEntries )
        throws MojoExecutionException
    {

        List<String> jarPaths = new ArrayList<String>();

        try
        {
            for ( String classLoaderEntry : classLoaderEntries )
            {
                URI uri = new URI( classLoaderEntry );
                File file = new File( uri );
                if ( !file.isDirectory() )
                {
                    jarPaths.add( file.getAbsolutePath() );
                }
            }
        }
        catch ( URISyntaxException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }

        return jarPaths;

    }
}
