package org.apache.maven.plugin.resources.remote;

/*
 * 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 java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Model;
import org.apache.maven.model.Resource;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.resources.remote.io.xpp3.SupplementalDataModelXpp3Reader;
import org.apache.maven.plugin.resources.remote.io.xpp3.RemoteResourcesBundleXpp3Reader;
import org.apache.maven.project.InvalidProjectModelException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectUtils;
import org.apache.maven.project.inheritance.ModelInheritanceAssembler;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.shared.downloader.DownloadException;
import org.apache.maven.shared.downloader.DownloadNotFoundException;
import org.apache.maven.shared.downloader.Downloader;
import org.apache.velocity.VelocityContext;
import org.codehaus.plexus.resource.ResourceManager;
import org.codehaus.plexus.resource.loader.FileResourceLoader;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.codehaus.plexus.velocity.VelocityComponent;

/**
 * Pull down resourceBundles containing remote resources and process the resources contained
 * inside the artifact.
 * <p/>
 * Resources that end in ".vm" are treated as velocity templates.  For those, the ".vm" is 
 * stripped off for the final artifact name and it's  fed through velocity to have properties
 * expanded, conditions processed, etc...
 * <p/>
 * Resources that don't end in ".vm" are copied "as is". 
 *
 * @goal process
 * @requiresDependencyResolution runtime
 * @phase generate-resources
 */
public class ProcessRemoteResourcesMojo
    extends AbstractMojo
{
    /**
     * The local repository taken from Maven's runtime. Typically $HOME/.m2/repository.
     *
     * @parameter expression="${localRepository}"
     */
    private ArtifactRepository localRepository;

    /**
     * The remote repositories used as specified in your POM.
     *
     * @parameter expression="${project.repositories}"
     */
    private List remoteRepositories;

    /**
     * The current Maven project.
     *
     * @parameter expression="${project}"
     */
    private MavenProject project;

    /**
     * The directory where processed resources will be placed for packaging.
     *
     * @parameter expression="${project.build.directory}/maven-shared-archive-resources"
     */
    private File outputDirectory;
    
    /**
     * The directory containing extra information appended to the generated resources.
     *
     * @parameter expression="${basedir}/src/main/appended-resources"
     */
    private File appendedResourcesDirectory;
    
    /**
     * Supplemental model data.  Useful when processing
     * artifacts with incomplete POM metadata.
     * 
     * By default, this Mojo looks for supplemental model
     * data in the file "${appendedResourcesDirectory}/supplemental-models.xml".
     * 
     * @parameter
     * @since 1.0-alpha-5
     */
    private String[] supplementalModels;
    
    /**
     * Map of artifacts to supplemental project object models.
     */
    private Map supplementModels;
    
    /**
     * Merges supplemental data model with artifact
     * metadata.  Useful when processing artifacts with
     * incomplete POM metadata.
     * 
     * @component
     */
    private ModelInheritanceAssembler inheritanceAssembler;

    /**
     * The resource bundles that will be retrieved and processed.
     *
     * @parameter
     * @required
     */
    private List resourceBundles;
  
    /**
     * Skip remote-resource processing
     * 
     * @parameter expression="${remoteresources.skip}" default-value="false"
     * @since 1.0-alpha-5
     */
    private boolean skip;

    /**
     * Additional properties to be passed to velocity.
     * <p/>
     * Several properties are automatically added:<br/>
     *   project - the current MavenProject <br/>
     *   projects - the list of dependency projects<br/>
     *   projectTimespan - the timespan of the current project (requires inceptionYear in pom)<br/>
     * <p/>
     * See <a href="http://maven.apache.org/ref/current/maven-project/apidocs/org/apache/maven/project/MavenProject.html">
     * the javadoc for MavenProject</a> for information about the properties on the MavenProject. 
     *
     * @parameter
     */
    private Map properties = new HashMap();
    
    /**
     * The list of resources defined for the project.
     *
     * @parameter expression="${project.resources}"
     * @required
     */
    private List resources;
     
    /**
     * Artifact downloader.
     *
     * @component
     */
    private Downloader downloader;

    /**
     * Velocity component.
     *
     * @component
     */
    private VelocityComponent velocity;

    // These two things make this horrible. Maven artifact is way too complicated and the relationship between
    // the model usage and maven-artifact needs to be reworked as well as all our tools that deal with it. The
    // ProjectUtils should be a component so I don't have to expose the container and artifact factory here. Can't
    // change it now because it's not released ...

    /**
     * Artifact repository factory component.
     *
     * @component
     */
    private ArtifactRepositoryFactory artifactRepositoryFactory;
    
    /**
     * Artifact factory, needed to create artifacts.
     *
     * @component
     */
    private ArtifactFactory artifactFactory;
    
    /**
     * The Maven session.
     *
     * @parameter expression="${session}"
     */
    private MavenSession mavenSession;
    
    /**
     * ProjectBuilder, needed to create projects from the artifacts.
     *
     * @component role="org.apache.maven.project.MavenProjectBuilder"
     * @required
     * @readonly
     */
    private MavenProjectBuilder mavenProjectBuilder;
    
    /**
     * @component
     * @required
     * @readonly
     */
    private ResourceManager locator;    

    public void execute()
        throws MojoExecutionException
    {
        if ( skip )
        {
            return;
        }
        if ( supplementalModels == null ) 
        {
            File sups = new File( appendedResourcesDirectory, "supplemental-models.xml" );
            if ( sups.exists() )
            {
                try 
                {
                    supplementalModels = new String[] { sups.toURL().toString() };
                }
                catch ( MalformedURLException e ) 
                {
                    //ignore
                    getLog().debug( "URL issue with supplemental-models.xml: " + e.toString() );
                }
            }
        }
        
                
        locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() );
        if ( appendedResourcesDirectory != null ) 
        {
            locator.addSearchPath( FileResourceLoader.ID, appendedResourcesDirectory.getAbsolutePath() );
        }
        locator.addSearchPath( "url", "" );
        locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) );

        ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
        try
        {
            Thread.currentThread().setContextClassLoader( this.getClass().getClassLoader() );
            
            validate();
    
            List resourceBundleArtifacts = downloadResourceBundles( resourceBundles );
            supplementModels = loadSupplements( supplementalModels );
            
            VelocityContext context = new VelocityContext( properties );
            configureVelocityContext( context );
            
            RemoteResourcesClassLoader classLoader 
                = new RemoteResourcesClassLoader( this.getClass().getClassLoader() );
            initalizeClassloader( classLoader, resourceBundleArtifacts );
            Thread.currentThread().setContextClassLoader( classLoader );
            
            processResourceBundles( classLoader, context );

            try
            {
                if ( outputDirectory.exists() )
                {
                    // ----------------------------------------------------------------------------
                    // Push our newly generated resources directory into the MavenProject so that
                    // these resources can be picked up by the process-resources phase.
                    // ----------------------------------------------------------------------------
                    Resource resource = new Resource();
                    resource.setDirectory( outputDirectory.getAbsolutePath() );
    
                    project.getResources().add( resource );
                    project.getTestResources().add( resource );
                    
                    // ----------------------------------------------------------------------------
                    // Write out archiver dot file
                    // ----------------------------------------------------------------------------
                    File dotFile = new File( project.getBuild().getDirectory(), ".plxarc" );
                    FileUtils.mkdir( dotFile.getParentFile().getAbsolutePath() );
                    FileUtils.fileWrite( dotFile.getAbsolutePath(), outputDirectory.getName() );
                }
            }
            catch ( IOException e )
            {
                throw new MojoExecutionException( "Error creating dot file for archiving instructions.", e );
            }
        }
        finally 
        {
            Thread.currentThread().setContextClassLoader( origLoader );            
        }
    }
    
    protected List getProjects()
        throws MojoExecutionException
    {
        List projects = new ArrayList();
        
        for ( Iterator it = project.getArtifacts().iterator() ; it.hasNext() ; ) 
        {
            Artifact artifact = (Artifact) it.next();
            try 
            {
                if ( artifact.isSnapshot() )
                {
                    VersionRange rng = VersionRange.createFromVersion( artifact.getBaseVersion() );
                    artifact = artifactFactory.createDependencyArtifact( artifact.getGroupId(),
                                                                         artifact.getArtifactId(),
                                                                         rng,
                                                                         artifact.getType(),
                                                                         artifact.getClassifier(),
                                                                         artifact.getScope(),
                                                                         null,
                                                                         artifact.isOptional() );
                }
                
                getLog().debug( "Building project for " + artifact );
                MavenProject p = null;
                try 
                {
                    p = mavenProjectBuilder.buildFromRepository( artifact,
                                                            remoteRepositories,
                                                            localRepository,
                                                            true );
                }
                catch ( InvalidProjectModelException e )
                {
                   getLog().warn( "Invalid project model for artifact [" 
                                  + artifact.getArtifactId() + ":" 
                                  + artifact.getGroupId() + ":" 
                                  + artifact.getVersion() + "]. " 
                                  + "It will be ignored by the remote resources Mojo." ); 
                   continue;
                }
                
    
                String supplementKey = generateSupplementMapKey( p.getModel().getGroupId(), 
                                                                 p.getModel().getArtifactId() );
                
                if ( supplementModels.containsKey( supplementKey ) )
                {
                    Model mergedModel = mergeModels( p.getModel(), 
                                                     (Model) supplementModels.get( supplementKey ) );
                    MavenProject mergedProject = new MavenProject( mergedModel );
                    projects.add( mergedProject );
                    getLog().debug( "Adding project with groupId [" + mergedProject.getGroupId() + "] (supplemented)" );
                }
                else 
                {
                    projects.add( p );
                    getLog().debug( "Adding project with groupId [" + p.getGroupId() + "]" );
                }
            }
            catch ( ProjectBuildingException e )
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return projects;
    }
    
    protected boolean copyResourceIfExists( File file, String relFileName )
        throws IOException 
    {
        for ( Iterator i = resources.iterator(); i.hasNext(); )
        {
            Resource resource = (Resource) i.next();
            File resourceDirectory = new File( resource.getDirectory() );

            if ( !resourceDirectory.exists() )
            {
                continue;
            }
            //TODO - really should use the resource includes/excludes and name mapping
            File source = new File( resourceDirectory, relFileName );
            
            if ( source.exists() 
                && !source.equals( file ) )
            {
                //TODO - should use filters here
                FileUtils.copyFile( source, file );
                
                //exclude the original (so eclipse doesn't complain about duplicate resources)
                resource.addExclude( relFileName );
                
                return true;
            }
            
        }
        return false;
    }
    
    protected void validate() throws MojoExecutionException
    {
        int bundleCount = 1;

        for ( Iterator i = resourceBundles.iterator(); i.hasNext(); )
        {
            String artifactDescriptor = (String) i.next();

            // groupId:artifactId:version
            String[] s = StringUtils.split( artifactDescriptor, ":" );

            if ( s.length != 3 )
            {
                String position;

                if ( bundleCount == 1 )
                {
                    position = "1st";
                }
                else if ( bundleCount == 2 )
                {
                    position = "2nd";
                }
                else if ( bundleCount == 3 )
                {
                    position = "3rd";
                }
                else
                {
                    position = bundleCount + "th";
                }

                throw new MojoExecutionException( "The " + position
                    + " resource bundle configured must specify a groupId, artifactId, and" 
                    + " version for a remote resource bundle. " 
                    + "Must be of the form <resourceBundle>groupId:artifactId:version</resourceBundle>" );
            }
            
            bundleCount++;
        }
                
    }
    
    protected void configureVelocityContext( VelocityContext context ) throws MojoExecutionException
    {
        String inceptionYear = project.getInceptionYear();
        String year = new SimpleDateFormat( "yyyy" ).format( new Date() );
        
        if ( StringUtils.isEmpty( inceptionYear ) )
        {
            getLog().info( "inceptionYear not specified, defaulting to " + year );
            inceptionYear = year;
        }
        context.put( "project", project );
        context.put( "projects", getProjects() );
        
        context.put( "presentYear", year );

        if ( inceptionYear.equals( year ) )
        {
            context.put( "projectTimespan", year );
        }
        else
        {
            context.put( "projectTimespan", inceptionYear + "-" + year );
        }
    }
    
    private List downloadResourceBundles( List resourceBundles ) throws MojoExecutionException
    {
        List resourceBundleArtifacts = new ArrayList();
        
        try
        {
            for ( Iterator i = resourceBundles.iterator(); i.hasNext(); )
            {
                String artifactDescriptor = (String) i.next();
                // groupId:artifactId:version
                String[] s = artifactDescriptor.split( ":" );
                File artifact = downloader.download( s[0], s[1], s[2], localRepository,
                        ProjectUtils.buildArtifactRepositories( remoteRepositories,
                            artifactRepositoryFactory,
                            mavenSession.getContainer() ) );
                
                resourceBundleArtifacts.add( artifact );
            }
        }
        catch ( DownloadException e )
        {
            throw new MojoExecutionException( "Error downloading resources JAR.", e );
        }
        catch ( DownloadNotFoundException e )
        {
            throw new MojoExecutionException( "Resources JAR cannot be found.", e );
        }
        catch ( InvalidRepositoryException e )
        {
            throw new MojoExecutionException( "Resources JAR cannot be found.", e );
        }
        
        return resourceBundleArtifacts;
    }
    
    private void initalizeClassloader( RemoteResourcesClassLoader cl, List artifacts ) throws MojoExecutionException
    {
        try
        {
            for ( Iterator i = artifacts.iterator(); i.hasNext(); )
            {
                File artifact = (File) i.next();
                cl.addURL( artifact.toURI().toURL() );            
            }
        }
        catch ( MalformedURLException e )
        {
            throw new MojoExecutionException( "Unable to configure resources classloader: " + e.getMessage(), e );
        }
    }
    
    protected void processResourceBundles( RemoteResourcesClassLoader classLoader, VelocityContext context )
        throws MojoExecutionException
    {
        InputStreamReader reader = null;
        
        try
        {
            
            for ( Enumeration e = classLoader.getResources( BundleRemoteResourcesMojo.RESOURCES_MANIFEST );
                  e.hasMoreElements(); )
            {
                URL url = (URL) e.nextElement();

                URLConnection conn = url.openConnection();

                conn.connect();

                reader = new InputStreamReader( conn.getInputStream() );
                               
                try 
                {

                    RemoteResourcesBundleXpp3Reader bundleReader = new RemoteResourcesBundleXpp3Reader();
    
                    RemoteResourcesBundle bundle = bundleReader.read( reader );
    
                    for ( Iterator i = bundle.getRemoteResources().iterator(); i.hasNext(); )
                    {
                        String bundleResource = (String) i.next();
    
                        String projectResource = bundleResource;
    
                        boolean doVelocity = false;
                        if ( projectResource.endsWith( ".vm" ) )
                        {
                            projectResource = projectResource.substring( 0, projectResource.length() - 3 );
                            doVelocity = true;
                        }
    
                        // Don't overwrite resource that are already being provided.
    
                        File f = new File( outputDirectory, projectResource );
    
                        FileUtils.mkdir( f.getParentFile().getAbsolutePath() );
    
                        if ( !copyResourceIfExists( f, projectResource ) )
                        {
                            if ( doVelocity ) 
                            {
                                PrintWriter writer = new PrintWriter( new FileWriter( f ) );
                                try 
                                {
                                    velocity.getEngine().mergeTemplate( bundleResource, context, writer );
        
                                    File appendedResourceFile = new File( appendedResourcesDirectory, projectResource );
                                    if ( appendedResourceFile.exists() ) 
                                    {
                                        FileReader freader = new FileReader( appendedResourceFile );
                                        BufferedReader breader = new BufferedReader( freader );
                                        
                                        String line = breader.readLine();
                               
                                        while ( line != null )
                                        {
                                            writer.println( line );
                                            line = breader.readLine();
                                        }
                                    }
                                }
                                finally
                                {
                                    writer.close();
                                }
                            }
                            else
                            {
                                URL resUrl = classLoader.getResource( bundleResource );
                                if ( resUrl != null )
                                {
                                    FileUtils.copyURLToFile( resUrl, f );
                                }
                            }
                        }
                    }
                }
                finally
                {
                    reader.close();
                }
            }
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Error finding remote resources manifests", e );
        }
        catch ( XmlPullParserException e )
        {
            throw new MojoExecutionException( "Error parsing remote resource bundle descriptor.", e );
        }
        catch ( Exception e )
        {
            throw new MojoExecutionException( "Error rendering velocity resource.", e );
        }
    }

    protected Model getSupplement( Xpp3Dom supplementModelXml )
        throws MojoExecutionException
    {
        MavenXpp3Reader modelReader = new MavenXpp3Reader();
        Model model = null;
        
        try
        {
            model = modelReader.read( new StringReader( supplementModelXml.toString() ) );
            String groupId = model.getGroupId();
            String artifactId = model.getArtifactId();
    
            if ( groupId == null 
                || groupId.trim().equals( "" ) )
            {
                throw new MojoExecutionException( "Supplemental project XML "
                                                  + "requires that a <groupId> element be present." );
            }
            
            if ( artifactId == null 
                || artifactId.trim().equals( "" ) )
            {
                throw new MojoExecutionException( "Supplemental project XML "
                                                  + "requires that a <artifactId> element be present." );
            }              
        } 
        catch ( IOException e )
        {
            getLog().warn( "Unable to read supplemental XML: " + e.getMessage(), e );
        } 
        catch ( XmlPullParserException e )
        {
            getLog().warn( "Unable to parse supplemental XML: " + e.getMessage(), e );
        }
        
        return model;
    }

    protected Model mergeModels( Model parent, Model child )
    {
        inheritanceAssembler.assembleModelInheritance( child, parent );  
        return child;
    }
    
    private static String generateSupplementMapKey( String groupId, String artifactId )
    {
        return groupId.trim() + ":" + artifactId.trim();
    }
    
    private Map loadSupplements( String models[] ) throws MojoExecutionException
    {  
        if ( models == null )
        {
            getLog().debug( "Supplemental data models won't be loaded.  " 
                            + "No models specified." );
            return Collections.EMPTY_MAP;
        }
        
        List supplements = new ArrayList();
        for ( int idx = 0; idx < models.length; idx++ ) 
        {
            String set = models[idx];
            getLog().debug( "Preparing ruleset: " + set );
            try
            {
                File f = locator.getResourceAsFile( set, getLocationTemp( set ) );
            
                if ( null == f || !f.exists() )
                {
                    throw new MavenReportException( "Cold not resolve " + set );
                }
                if ( !f.canRead() )
                {
                    throw new MavenReportException( "Supplemental data models won't be loaded. " 
                                                    + "File " + f.getAbsolutePath() 
                                                    + " cannot be read, check permissions on the file." );
                }
                
                getLog().debug( "Loading supplemental models from " + f.getAbsolutePath() );
                
                SupplementalDataModelXpp3Reader reader = new SupplementalDataModelXpp3Reader();
                SupplementalDataModel supplementalModel = reader.read( new FileReader( f ) );
                supplements.addAll( supplementalModel.getSupplement() );
            } 
            catch ( Exception e )
            {
                String msg = "Error loading supplemental data models: " + e.getMessage();
                getLog().error( msg, e );
                throw new MojoExecutionException( msg, e );
            }
        }

        getLog().debug( "Loading supplements complete." );
        
        Map supplementMap = new HashMap();
        for ( Iterator i = supplements.iterator(); i.hasNext(); )
        {
            Supplement sd = (Supplement) i.next();
            
            Xpp3Dom dom = (Xpp3Dom) sd.getProject();
            
            Model m = getSupplement( dom );
            supplementMap.put( generateSupplementMapKey( m.getGroupId(), m.getArtifactId() ), m );
        }
        
        return supplementMap;
    }
    
    /**
     * Convenience method to get the location of the specified file name.
     *
     * @param name the name of the file whose location is to be resolved
     * @return a String that contains the absolute file name of the file
     */
    private String getLocationTemp( String name )
    {
        String loc = name;
        if ( loc.indexOf( '/' ) != -1 )
        {
            loc = loc.substring( loc.lastIndexOf( '/' ) + 1 );
        }
        if ( loc.indexOf( '\\' ) != -1 )
        {
            loc = loc.substring( loc.lastIndexOf( '\\' ) + 1 );
        }
        getLog().debug( "Before: " + name + " After: " + loc );
        return loc;
    }
    
}
