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.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.io.output.DeferredFileOutputStream;
import org.apache.maven.ProjectDependenciesResolver;
import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Model;
import org.apache.maven.model.Organization;
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.RemoteResourcesBundleXpp3Reader;
import org.apache.maven.plugin.resources.remote.io.xpp3.SupplementalDataModelXpp3Reader;
import org.apache.maven.plugins.annotations.Component;
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.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.artifact.InvalidDependencyVersionException;
import org.apache.maven.project.inheritance.ModelInheritanceAssembler;
import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter;
import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
import org.apache.maven.shared.artifact.filter.collection.GroupIdFilter;
import org.apache.maven.shared.artifact.filter.collection.ProjectTransitivityFilter;
import org.apache.maven.shared.artifact.filter.collection.ScopeFilter;
import org.apache.maven.shared.filtering.MavenFileFilter;
import org.apache.maven.shared.filtering.MavenFileFilterRequest;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.log.LogChute;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.codehaus.plexus.resource.ResourceManager;
import org.codehaus.plexus.resource.loader.FileResourceLoader;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 * <p>
 * Pull down resourceBundles containing remote resources and process the resources contained inside. When that is done,
 * the resources are injected into the current (in-memory) Maven project, making them available to the process-resources
 * phase.
 * </p>
 * <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>
 * <p/>
 * Resources that don't end in ".vm" are copied "as is".
 */
// NOTE: Removed the following in favor of maven-artifact-resolver library, for MRRESOURCES-41
// If I leave this intact, interdependent projects within the reactor that haven't been built
// (remember, this runs in the generate-resources phase) will cause the build to fail.
//
// @requiresDependencyResolution test
@Mojo( name = "process", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, threadSafe = true )
public class ProcessRemoteResourcesMojo
    extends AbstractMojo
    implements LogChute
{

    private static final String TEMPLATE_SUFFIX = ".vm";

    /**
     * <p>
     * In cases where a local resource overrides one from a remote resource bundle, that resource should be filtered if
     * the resource set specifies it. In those cases, this parameter defines the list of delimiters for filterable
     * expressions. These delimiters are specified in the form 'beginToken*endToken'. If no '*' is given, the delimiter
     * is assumed to be the same for start and end.
     * </p>
     * <p>
     * So, the default filtering delimiters might be specified as:
     * </p>
     * 
     * <pre>
     * &lt;delimiters&gt;
     *   &lt;delimiter&gt;${*}&lt/delimiter&gt;
     *   &lt;delimiter&gt;@&lt/delimiter&gt;
     * &lt;/delimiters&gt;
     * </pre>
     * <p/>
     * Since the '@' delimiter is the same on both ends, we don't need to specify '@*@' (though we can).
     *
     * @since 1.1
     */
    @Parameter
    protected List<String> filterDelimiters;

    /**
     * @since 1.1
     */
    @Parameter( defaultValue = "true" )
    protected boolean useDefaultFilterDelimiters;

    /**
     * If true, only generate resources in the directory of the root project in a multimodule build.
     * Dependencies from all modules will be aggregated before resource-generation takes place.
     *
     * @since 1.1
     */
    @Parameter( defaultValue = "false" )
    protected boolean runOnlyAtExecutionRoot;

    /**
     * Used for calculation of execution-root for {@link ProcessRemoteResourcesMojo#runOnlyAtExecutionRoot}.
     */
    @Parameter( defaultValue = "${basedir}", readonly = true, required = true )
    protected File basedir;

    /**
     * The character encoding scheme to be applied when filtering resources.
     */
    @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
    protected String encoding;

    /**
     * The local repository taken from Maven's runtime. Typically <code>$HOME/.m2/repository</code>.
     */
    @Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
    private ArtifactRepository localRepository;

    /**
     * List of Remote Repositories used by the resolver.
     */
    @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true )
    private List<ArtifactRepository> remoteArtifactRepositories;

    /**
     * The current Maven project.
     */
    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    private MavenProject project;

    /**
     * The directory where processed resources will be placed for packaging.
     */
    @Parameter( defaultValue = "${project.build.directory}/maven-shared-archive-resources" )
    private File outputDirectory;

    /**
     * The directory containing extra information appended to the generated resources.
     */
    @Parameter( defaultValue = "${basedir}/src/main/appended-resources" )
    private File appendedResourcesDirectory;

    /**
     * Supplemental model data. Useful when processing
     * artifacts with incomplete POM metadata.
     * <p/>
     * By default, this Mojo looks for supplemental model data in the file
     * "<code>${appendedResourcesDirectory}/supplemental-models.xml</code>".
     *
     * @since 1.0-alpha-5
     */
    @Parameter
    private String[] supplementalModels;

    /**
     * List of artifacts that are added to the search path when looking
     * for supplementalModels, expressed with <code>groupId:artifactId:version[:type[:classifier]]</code> format.
     *
     * @since 1.1
     */
    @Parameter
    private List<String> supplementalModelArtifacts;

    /**
     * Map of artifacts to supplemental project object models.
     */
    private Map<String, Model> 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,
     * expressed with <code>groupId:artifactId:version[:type[:classifier]]</code> format.
     */
    @Parameter( required = true )
    private List<String> resourceBundles;

    /**
     * Skip remote-resource processing
     *
     * @since 1.0-alpha-5
     */
    @Parameter( property = "remoteresources.skip", defaultValue = "false" )
    private boolean skip;

    /**
     * Attaches the resources to the main build of the project as a resource directory.
     *
     * @since 1.5
     */
    @Parameter( defaultValue = "true", property = "attachToMain" )
    private boolean attachToMain;

    /**
     * Attaches the resources to the test build of the project as a resource directory.
     *
     * @since 1.5
     */
    @Parameter( defaultValue = "true", property = "attachToTest" )
    private boolean attachToTest;

    /**
     * Additional properties to be passed to Velocity.
     * <p/>
     * Several properties are automatically added:<ul>
     * <li><code>project</code> - the current MavenProject </li>
     * <li><code>projects</code> - the list of dependency projects</li>
     * <li><code>projectsSortedByOrganization</code> - the list of dependency projects sorted by organization</li>
     * <li><code>projectTimespan</code> - the timespan of the current project (requires inceptionYear in pom)</li>
     * <li><code>locator</code> - the ResourceManager that can be used to retrieve additional resources</li>
     * </ul>
     * See <a
     * href="https://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<String, Object> properties = new HashMap<>();

    /**
     * Whether to include properties defined in the project when filtering resources.
     *
     * @since 1.2
     */
    @Parameter( defaultValue = "false" )
    protected boolean includeProjectProperties = false;

    /**
     * When the result of velocity transformation fits in memory, it is compared with the actual contents on disk
     * to eliminate unnecessary destination file overwrite. This improves build times since further build steps
     * typically rely on the modification date.
     *
     * @since 1.6
     */
    @Parameter( defaultValue = "5242880" )
    protected int velocityFilterInMemoryThreshold = 5 * 1024 * 1024;

    /**
     * The list of resources defined for the project.
     */
    @Parameter( defaultValue = "${project.resources}", readonly = true, required = true )
    private List<Resource> resources;

    /**
     * Artifact Resolver, needed to resolve and download the {@code resourceBundles}.
     */
    @Component
    private ArtifactResolver artifactResolver;

    /**
     * Filtering support, for local resources that override those in the remote bundle.
     */
    @Component
    private MavenFileFilter fileFilter;

    /**
     * Artifact factory, needed to create artifacts.
     */
    @Component
    private ArtifactFactory artifactFactory;

    /**
     * The Maven session.
     */
    @Parameter( defaultValue = "${session}", readonly = true, required = true )
    private MavenSession mavenSession;

    /**
     * ProjectBuilder, needed to create projects from the artifacts.
     */
    @Component( role = MavenProjectBuilder.class )
    private MavenProjectBuilder mavenProjectBuilder;

    /**
     */
    @Component
    private ResourceManager locator;

    /**
     * Scope to include. An Empty string indicates all scopes (default is "runtime").
     *
     * @since 1.0
     */
    @Parameter( property = "includeScope", defaultValue = "runtime" )
    protected String includeScope;

    /**
     * Scope to exclude. An Empty string indicates no scopes (default).
     *
     * @since 1.0
     */
    @Parameter( property = "excludeScope", defaultValue = "" )
    protected String excludeScope;

    /**
     * When resolving project dependencies, specify the scopes to include.
     * The default is the same as "includeScope" if there are no exclude scopes set.
     * Otherwise, it defaults to "test" to grab all the dependencies so the
     * exclude filters can filter out what is not needed.
     * 
     * @since 1.5
     */
    @Parameter
    private String[] resolveScopes;

    /**
     * Comma separated list of Artifact names too exclude.
     *
     * @since 1.0
     */
    @Parameter( property = "excludeArtifactIds", defaultValue = "" )
    protected String excludeArtifactIds;

    /**
     * Comma separated list of Artifact names to include.
     *
     * @since 1.0
     */
    @Parameter( property = "includeArtifactIds", defaultValue = "" )
    protected String includeArtifactIds;

    /**
     * Comma separated list of GroupId Names to exclude.
     *
     * @since 1.0
     */
    @Parameter( property = "excludeGroupIds", defaultValue = "" )
    protected String excludeGroupIds;

    /**
     * Comma separated list of GroupIds to include.
     *
     * @since 1.0
     */
    @Parameter( property = "includeGroupIds", defaultValue = "" )
    protected String includeGroupIds;

    /**
     * If we should exclude transitive dependencies
     *
     * @since 1.0
     */
    @Parameter( property = "excludeTransitive", defaultValue = "false" )
    protected boolean excludeTransitive;

    /**
     * Timestamp for reproducible output archive entries, either formatted as ISO 8601
     * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
     * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
     */
    @Parameter( defaultValue = "${project.build.outputTimestamp}" )
    private String outputTimestamp;

    /**
     */
    @Component( hint = "default" )
    protected ProjectDependenciesResolver dependencyResolver;

    private VelocityEngine velocity;

    @Override
    @SuppressWarnings( "unchecked" )
    public void execute()
        throws MojoExecutionException
    {
        if ( skip )
        {
            getLog().info( "Skipping remote resources execution." );
            return;
        }

        if ( StringUtils.isEmpty( encoding ) )
        {
            getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
                               + ", i.e. build is platform dependent!" );
        }

        if ( runOnlyAtExecutionRoot && !project.isExecutionRoot() )
        {
            getLog().info( "Skipping remote-resource generation in this project because it's not the Execution Root" );
            return;
        }

        if ( resolveScopes == null )
        {
            resolveScopes =
                new String[] { StringUtils.isEmpty( excludeScope ) ? this.includeScope : Artifact.SCOPE_TEST };
        }

        if ( supplementalModels == null )
        {
            File sups = new File( appendedResourcesDirectory, "supplemental-models.xml" );
            if ( sups.exists() )
            {
                try
                {
                    supplementalModels = new String[] { sups.toURI().toURL().toString() };
                }
                catch ( MalformedURLException e )
                {
                    // ignore
                    getLog().debug( "URL issue with supplemental-models.xml: " + e.toString() );
                }
            }
        }

        configureLocator();

        if ( includeProjectProperties )
        {
            final Properties projectProperties = project.getProperties();
            for ( Object key : projectProperties.keySet() )
            {
                properties.put( key.toString(), projectProperties.get( key ).toString() );
            }
        }

        ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
        try
        {
            validate();

            List<File> resourceBundleArtifacts = downloadBundles( resourceBundles );
            supplementModels = loadSupplements( supplementalModels );

            ClassLoader classLoader = initalizeClassloader( resourceBundleArtifacts );

            Thread.currentThread().setContextClassLoader( classLoader );

            velocity = new VelocityEngine();
            velocity.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, this );
            velocity.setProperty( "resource.loader", "classpath" );
            velocity.setProperty( "classpath.resource.loader.class", ClasspathResourceLoader.class.getName() );
            velocity.init();

            VelocityContext context = buildVelocityContext( properties );

            processResourceBundles( classLoader, context );

            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() );
                // MRRESOURCES-61 handle main and test resources separately
                if ( attachToMain )
                {
                    project.getResources().add( resource );
                }
                if ( attachToTest )
                {
                    project.getTestResources().add( resource );
                }

                // ----------------------------------------------------------------------------
                // Write out archiver dot file
                // ----------------------------------------------------------------------------
                try
                {
                    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 );
        }
    }

    private void configureLocator()
        throws MojoExecutionException
    {
        if ( supplementalModelArtifacts != null && !supplementalModelArtifacts.isEmpty() )
        {
            List<File> artifacts = downloadBundles( supplementalModelArtifacts );

            for ( File artifact : artifacts )
            {
                if ( artifact.isDirectory() )
                {
                    locator.addSearchPath( FileResourceLoader.ID, artifact.getAbsolutePath() );
                }
                else
                {
                    try
                    {
                        locator.addSearchPath( "jar", "jar:" + artifact.toURI().toURL().toExternalForm() );
                    }
                    catch ( MalformedURLException e )
                    {
                        throw new MojoExecutionException( "Could not use jar " + artifact.getAbsolutePath(), e );
                    }
                }
            }

        }

        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() ) );
    }

    @SuppressWarnings( "unchecked" )
    protected List<MavenProject> getProjects()
    {
        List<MavenProject> projects = new ArrayList<>();

        // add filters in well known order, least specific to most specific
        FilterArtifacts filter = new FilterArtifacts();

        Set<Artifact> artifacts = resolveProjectArtifacts();
        if ( this.excludeTransitive )
        {
            Set<Artifact> depArtifacts;
            if ( runOnlyAtExecutionRoot )
            {
                depArtifacts = aggregateProjectDependencyArtifacts();
            }
            else
            {
                depArtifacts = project.getDependencyArtifacts();
            }
            filter.addFilter( new ProjectTransitivityFilter( depArtifacts, true ) );
        }

        filter.addFilter( new ScopeFilter( this.includeScope, this.excludeScope ) );
        filter.addFilter( new GroupIdFilter( this.includeGroupIds, this.excludeGroupIds ) );
        filter.addFilter( new ArtifactIdFilter( this.includeArtifactIds, this.excludeArtifactIds ) );

        // perform filtering
        try
        {
            artifacts = filter.filter( artifacts );
        }
        catch ( ArtifactFilterException e )
        {
            throw new IllegalStateException( e.getMessage(), e );
        }

        for ( Artifact artifact : artifacts )
        {
            try
            {
                List<ArtifactRepository> remoteRepo = remoteArtifactRepositories;
                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;
                try
                {
                    p = mavenProjectBuilder.buildFromRepository( artifact, remoteRepo, localRepository );
                }
                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(), supplementModels.get( supplementKey ) );
                    MavenProject mergedProject = new MavenProject( mergedModel );
                    projects.add( mergedProject );
                    mergedProject.setArtifact( artifact );
                    mergedProject.setVersion( artifact.getVersion() );
                    getLog().debug( "Adding project with groupId [" + mergedProject.getGroupId() + "] (supplemented)" );
                }
                else
                {
                    projects.add( p );
                    getLog().debug( "Adding project with groupId [" + p.getGroupId() + "]" );
                }
            }
            catch ( ProjectBuildingException e )
            {
                throw new IllegalStateException( e.getMessage(), e );
            }
        }
        Collections.sort( projects, new ProjectComparator() );
        return projects;
    }

    private Set<Artifact> resolveProjectArtifacts()
    {
        try
        {
            if ( runOnlyAtExecutionRoot )
            {
                List<MavenProject> projects = mavenSession.getSortedProjects();
                return dependencyResolver.resolve( projects, Arrays.asList( resolveScopes ), mavenSession );
            }
            else
            {
                return dependencyResolver.resolve( project, Arrays.asList( resolveScopes ), mavenSession );
            }
        }
        catch ( ArtifactResolutionException e )
        {
            throw new IllegalStateException( "Failed to resolve dependencies for one or more projects in the reactor. "
                + "Reason: " + e.getMessage(), e );
        }
        catch ( ArtifactNotFoundException e )
        {
            throw new IllegalStateException( "Failed to resolve dependencies for one or more projects in the reactor. "
                + "Reason: " + e.getMessage(), e );
        }
    }

    @SuppressWarnings( "unchecked" )
    private Set<Artifact> aggregateProjectDependencyArtifacts()
    {
        Set<Artifact> artifacts = new LinkedHashSet<>();

        List<MavenProject> projects = mavenSession.getSortedProjects();
        for ( MavenProject p : projects )
        {
            if ( p.getDependencyArtifacts() == null )
            {
                try
                {
                    Set<Artifact> depArtifacts = p.createArtifacts( artifactFactory, null, null );

                    if ( depArtifacts != null && !depArtifacts.isEmpty() )
                    {
                        for ( Artifact artifact : depArtifacts )
                        {
                            if ( artifact.getVersion() == null && artifact.getVersionRange() != null )
                            {
                                // Version is required for equality comparison between artifacts,
                                // but it is not needed for our purposes of filtering out
                                // transitive dependencies (which requires only groupId/artifactId).
                                // Therefore set an arbitrary version if missing.
                                artifact.setResolvedVersion( Artifact.LATEST_VERSION );
                            }
                            artifacts.add( artifact );
                        }
                    }
                }
                catch ( InvalidDependencyVersionException e )
                {
                    throw new IllegalStateException( "Failed to create dependency artifacts for: " + p.getId()
                        + ". Reason: " + e.getMessage(), e );
                }
            }
        }

        return artifacts;
    }

    protected Map<Organization, List<MavenProject>> getProjectsSortedByOrganization( List<MavenProject> projects )
    {
        Map<Organization, List<MavenProject>> organizations =
            new TreeMap<>( new OrganizationComparator() );
        List<MavenProject> unknownOrganization = new ArrayList<>();

        for ( MavenProject p : projects )
        {
            if ( p.getOrganization() != null && StringUtils.isNotEmpty( p.getOrganization().getName() ) )
            {
                List<MavenProject> sortedProjects = organizations.get( p.getOrganization() );
                if ( sortedProjects == null )
                {
                    sortedProjects = new ArrayList<>();
                }
                sortedProjects.add( p );

                organizations.put( p.getOrganization(), sortedProjects );
            }
            else
            {
                unknownOrganization.add( p );
            }
        }
        if ( !unknownOrganization.isEmpty() )
        {
            Organization unknownOrg = new Organization();
            unknownOrg.setName( "an unknown organization" );
            organizations.put( unknownOrg, unknownOrganization );
        }

        return organizations;
    }

    protected boolean copyResourceIfExists( File file, String relFileName, VelocityContext context )
        throws IOException, MojoExecutionException
    {
        for ( Resource resource : resources )
        {
            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 );
            File templateSource = new File( resourceDirectory, relFileName + TEMPLATE_SUFFIX );

            if ( !source.exists() && templateSource.exists() )
            {
                source = templateSource;
            }

            if ( source.exists() && !source.equals( file ) )
            {
                if ( source == templateSource )
                {
                    try ( DeferredFileOutputStream os = 
                                    new DeferredFileOutputStream( velocityFilterInMemoryThreshold, file ) )
                    {
                        try ( Reader reader = getReader( source ); Writer writer = getWriter( os ) )
                        {
                            velocity.evaluate( context, writer, "", reader );
                        }
                        catch ( ParseErrorException | MethodInvocationException | ResourceNotFoundException e )
                        {
                            throw new MojoExecutionException( "Error rendering velocity resource: " + source, e );
                        }
                        fileWriteIfDiffers( os );
                    }
                }
                else if ( resource.isFiltering() )
                {

                    MavenFileFilterRequest req = setupRequest( resource, source, file );

                    try
                    {
                        fileFilter.copyFile( req );
                    }
                    catch ( MavenFilteringException e )
                    {
                        throw new MojoExecutionException( "Error filtering resource: " + source, e );
                    }
                }
                else
                {
                    FileUtils.copyFile( source, file );
                }

                // exclude the original (so eclipse doesn't complain about duplicate resources)
                resource.addExclude( relFileName );

                return true;
            }

        }
        return false;
    }

    private Reader getReader( File source ) throws IOException
    {
        if ( encoding != null )
        {
            return new InputStreamReader( new FileInputStream( source ), encoding );
        }
        else
        {
            return ReaderFactory.newPlatformReader( source );
        }
    }
    
    private Writer getWriter( OutputStream os ) throws IOException
    {
        if ( encoding != null )
        {
            return new OutputStreamWriter( os, encoding );
        }
        else
        {
            return WriterFactory.newPlatformWriter( os );
        }
    }

    /**
     * If the transformation result fits in memory and the destination file already exists
     * then both are compared.
     * <p>If destination file is byte-by-byte equal, then it is not overwritten.
     * This improves subsequent compilation times since upstream plugins property see that
     * the resource was not modified.
     * <p>Note: the method should be called after {@link org.apache.commons.io.output.DeferredFileOutputStream#close}
     *
     * @param outStream Deferred stream
     * @throws IOException
     */
    private void fileWriteIfDiffers( DeferredFileOutputStream outStream )
        throws IOException
    {
        File file = outStream.getFile();
        if ( outStream.isThresholdExceeded() )
        {
            getLog().info( "File " + file + " was overwritten due to content limit threshold "
                    + outStream.getThreshold() + " reached" );
            return;
        }
        boolean needOverwrite = true;

        if ( file.exists() )
        {
            try ( InputStream is = new FileInputStream( file ) )
            {
                final InputStream newContents = new ByteArrayInputStream( outStream.getData() );
                needOverwrite = !IOUtil.contentEquals( is, newContents );
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "File " + file + " contents "
                                        + ( needOverwrite ? "differs" : "does not differ" ) );
                }
            }
        }

        if ( !needOverwrite )
        {
            getLog().debug( "File " + file + " is up to date" );
            return;
        }
        getLog().debug( "Writing " + file );
        
        try ( OutputStream os = new FileOutputStream( file ) )
        {
            outStream.writeTo( os );
        }
    }

    private MavenFileFilterRequest setupRequest( Resource resource, File source, File file )
    {
        MavenFileFilterRequest req = new MavenFileFilterRequest();
        req.setFrom( source );
        req.setTo( file );
        req.setFiltering( resource.isFiltering() );

        req.setMavenProject( project );
        req.setMavenSession( mavenSession );
        req.setInjectProjectBuildFilters( true );

        if ( encoding != null )
        {
            req.setEncoding( encoding );
        }

        if ( filterDelimiters != null && !filterDelimiters.isEmpty() )
        {
            LinkedHashSet<String> delims = new LinkedHashSet<>();
            if ( useDefaultFilterDelimiters )
            {
                delims.addAll( req.getDelimiters() );
            }

            for ( String delim : filterDelimiters )
            {
                if ( delim == null )
                {
                    delims.add( "${*}" );
                }
                else
                {
                    delims.add( delim );
                }
            }

            req.setDelimiters( delims );
        }

        return req;
    }

    protected void validate()
        throws MojoExecutionException
    {
        int bundleCount = 1;

        for ( String artifactDescriptor : resourceBundles )
        {
            // groupId:artifactId:version, groupId:artifactId:version:type
            // or groupId:artifactId:version:type:classifier
            String[] s = StringUtils.split( artifactDescriptor, ":" );

            if ( s.length < 3 || s.length > 5 )
            {
                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, "
                    + " version and, optionally, type and classifier for a remote resource bundle. "
                    + "Must be of the form <resourceBundle>groupId:artifactId:version</resourceBundle>, "
                    + "<resourceBundle>groupId:artifactId:version:type</resourceBundle> or "
                    + "<resourceBundle>groupId:artifactId:version:type:classifier</resourceBundle>" );
            }

            bundleCount++;
        }

    }

    private static final String KEY_PROJECTS = "projects";
    private static final String KEY_PROJECTS_ORGS = "projectsSortedByOrganization";

    protected VelocityContext buildVelocityContext( Map<String, Object> properties )
        throws MojoExecutionException
    {
        // the following properties are expensive to calculate, so we provide them lazily
        VelocityContext context = new VelocityContext( properties )
        {
            @Override
            public Object internalGet( String key )
            {
                Object result = super.internalGet( key );
                if ( result == null && key != null && key.startsWith( KEY_PROJECTS ) && containsKey( key ) )
                {
                    // calculate and put projects* properties
                    List<MavenProject> projects = getProjects();
                    put( KEY_PROJECTS, projects );
                    put( KEY_PROJECTS_ORGS, getProjectsSortedByOrganization( projects ) );
                    return super.internalGet( key );
                }
                return result;
            }
        };
        // to have a consistent getKeys()/containsKey() behaviour, keys must be present from the start
        context.put( KEY_PROJECTS, null );
        context.put( KEY_PROJECTS_ORGS, null );
        // the following properties are cheap to calculate, so we provide them eagerly

        // Reproducible Builds: try to use reproducible output timestamp 
        MavenArchiver archiver = new MavenArchiver();
        Date outputDate = archiver.parseOutputTimestamp( outputTimestamp );

        String inceptionYear = project.getInceptionYear();
        String year = new SimpleDateFormat( "yyyy" ).format( ( outputDate == null ) ? new Date() : outputDate );

        if ( StringUtils.isEmpty( inceptionYear ) )
        {
            if ( getLog().isDebugEnabled() )
            {
                getLog().debug( "inceptionYear not specified, defaulting to " + year );
            }

            inceptionYear = year;
        }
        context.put( "project", project );
        context.put( "presentYear", year );
        context.put( "locator", locator );

        if ( inceptionYear.equals( year ) )
        {
            context.put( "projectTimespan", year );
        }
        else
        {
            context.put( "projectTimespan", inceptionYear + "-" + year );
        }
        return context;
    }

    private List<File> downloadBundles( List<String> bundles )
        throws MojoExecutionException
    {
        List<File> bundleArtifacts = new ArrayList<>();

        try
        {
            for ( String artifactDescriptor : bundles )
            {
                getLog().info( "Preparing remote bundle " + artifactDescriptor );
                // groupId:artifactId:version[:type[:classifier]]
                String[] s = artifactDescriptor.split( ":" );

                File artifactFile = null;
                // check if the artifact is part of the reactor
                if ( mavenSession != null )
                {
                    List<MavenProject> list = mavenSession.getSortedProjects();
                    for ( MavenProject p : list )
                    {
                        if ( s[0].equals( p.getGroupId() ) && s[1].equals( p.getArtifactId() )
                            && s[2].equals( p.getVersion() ) )
                        {
                            if ( s.length >= 4 && "test-jar".equals( s[3] ) )
                            {
                                artifactFile = new File( p.getBuild().getTestOutputDirectory() );
                            }
                            else
                            {
                                artifactFile = new File( p.getBuild().getOutputDirectory() );
                            }
                        }
                    }
                }
                if ( artifactFile == null || !artifactFile.exists() )
                {
                    String type = ( s.length >= 4 ? s[3] : "jar" );
                    String classifier = ( s.length == 5 ? s[4] : null );
                    Artifact artifact =
                        artifactFactory.createDependencyArtifact( s[0], s[1], VersionRange.createFromVersion( s[2] ),
                                                                  type, classifier, Artifact.SCOPE_RUNTIME );

                    artifactResolver.resolve( artifact, remoteArtifactRepositories, localRepository );

                    artifactFile = artifact.getFile();
                }
                bundleArtifacts.add( artifactFile );
            }
        }
        catch ( ArtifactResolutionException e )
        {
            throw new MojoExecutionException( "Error downloading resources archive.", e );
        }
        catch ( ArtifactNotFoundException e )
        {
            throw new MojoExecutionException( "Resources archive cannot be found.", e );
        }

        return bundleArtifacts;
    }

    private ClassLoader initalizeClassloader( List<File> artifacts )
        throws MojoExecutionException
    {
        RemoteResourcesClassLoader cl = new RemoteResourcesClassLoader( null );
        try
        {
            for ( File artifact : artifacts )
            {
                cl.addURL( artifact.toURI().toURL() );
            }
            return cl;
        }
        catch ( MalformedURLException e )
        {
            throw new MojoExecutionException( "Unable to configure resources classloader: " + e.getMessage(), e );
        }
    }

    protected void processResourceBundles( ClassLoader classLoader, VelocityContext context )
        throws MojoExecutionException
    {
        List<Map.Entry<String, RemoteResourcesBundle>> remoteResources =
            new ArrayList<>();
        int bundleCount = 0;
        int resourceCount = 0;

        // list remote resources form bundles
        try
        {
            RemoteResourcesBundleXpp3Reader bundleReader = new RemoteResourcesBundleXpp3Reader();

            for ( Enumeration<URL> e =
                classLoader.getResources( BundleRemoteResourcesMojo.RESOURCES_MANIFEST ); e.hasMoreElements(); )
            {
                URL url = e.nextElement();
                bundleCount++;
                getLog().debug( "processResourceBundle on bundle#" + bundleCount + " " + url );

                RemoteResourcesBundle bundle;
                
                try ( InputStream in = url.openStream() )
                {
                    bundle = bundleReader.read( in );
                }

                int n = 0;
                for ( String bundleResource : bundle.getRemoteResources() )
                {
                    n++;
                    resourceCount++;
                    getLog().debug( "bundle#" + bundleCount + " resource#" + n + " " + bundleResource );
                    remoteResources.add( new AbstractMap.SimpleEntry<>( bundleResource,
                                                                                                     bundle ) );
                }
            }
        }
        catch ( IOException ioe )
        {
            throw new MojoExecutionException( "Error finding remote resources manifests", ioe );
        }
        catch ( XmlPullParserException xppe )
        {
            throw new MojoExecutionException( "Error parsing remote resource bundle descriptor.", xppe );
        }

        getLog().info( "Copying " + resourceCount + " resource" + ( ( resourceCount > 1 ) ? "s" : "" ) + " from "
            + bundleCount + " bundle" + ( ( bundleCount > 1 ) ? "s" : "" ) + "." );

        String velocityResource = null;
        try
        {

            for ( Map.Entry<String, RemoteResourcesBundle> entry : remoteResources )
            {
                String bundleResource = entry.getKey();
                RemoteResourcesBundle bundle = entry.getValue();

                String projectResource = bundleResource;

                boolean doVelocity = false;
                if ( projectResource.endsWith( TEMPLATE_SUFFIX ) )
                {
                    projectResource = projectResource.substring( 0, projectResource.length() - 3 );
                    velocityResource = bundleResource;
                    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, context ) )
                {
                    if ( doVelocity )
                    {
                        try ( DeferredFileOutputStream os =
                                        new DeferredFileOutputStream( velocityFilterInMemoryThreshold, f ) )
                        {
                            try ( Writer writer = bundle.getSourceEncoding() == null ? new OutputStreamWriter( os )
                                            : new OutputStreamWriter( os, bundle.getSourceEncoding() ) )
                            {
                                if ( bundle.getSourceEncoding() == null )
                                {
                                    // TODO: Is this correct? Shouldn't we behave like the rest of maven and fail
                                    // down to JVM default instead ISO-8859-1 ?
                                    velocity.mergeTemplate( bundleResource, "ISO-8859-1", context, writer );
                                }
                                else
                                {
                                    velocity.mergeTemplate( bundleResource, bundle.getSourceEncoding(), context,
                                                            writer );
                                }
                            }
                            fileWriteIfDiffers( os );
                        }
                    }
                    else
                    {
                        URL resUrl = classLoader.getResource( bundleResource );
                        if ( resUrl != null )
                        {
                            FileUtils.copyURLToFile( resUrl, f );
                        }
                    }

                    File appendedResourceFile = new File( appendedResourcesDirectory, projectResource );
                    File appendedVmResourceFile = new File( appendedResourcesDirectory, projectResource + ".vm" );

                    if ( appendedResourceFile.exists() )
                    {
                        getLog().info( "Copying appended resource: " + projectResource );
                        try ( InputStream in = new FileInputStream( appendedResourceFile );
                              OutputStream out = new FileOutputStream( f, true ) )
                        {
                            IOUtil.copy( in, out );
                        }
                        
                    }
                    else if ( appendedVmResourceFile.exists() )
                    {
                        getLog().info( "Filtering appended resource: " + projectResource + ".vm" );
                        

                        try ( Reader reader = new FileReader( appendedVmResourceFile ); 
                              Writer writer = getWriter( bundle, f ) )
                        {
                            Velocity.init();
                            Velocity.evaluate( context, writer, "remote-resources", reader );
                        }
                    }
                }
            }
        }
        catch ( IOException ioe )
        {
            throw new MojoExecutionException( "Error reading remote resource", ioe );
        }
        catch ( VelocityException e )
        {
            throw new MojoExecutionException( "Error rendering Velocity resource '" + velocityResource + "'", e );
        }
    }

    private Writer getWriter( RemoteResourcesBundle bundle, File f )
        throws IOException, UnsupportedEncodingException, FileNotFoundException
    {
        Writer writer;
        if ( bundle.getSourceEncoding() == null )
        {
            writer = new PrintWriter( new FileWriter( f, true ) );
        }
        else
        {
            writer = new PrintWriter( new OutputStreamWriter( new FileOutputStream( f, true ),
                                                              bundle.getSourceEncoding() ) );
        }
        return writer;
    }

    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<String, Model> loadSupplements( String models[] )
        throws MojoExecutionException
    {
        if ( models == null )
        {
            getLog().debug( "Supplemental data models won't be loaded.  " + "No models specified." );
            return Collections.emptyMap();
        }

        List<Supplement> supplements = new ArrayList<>();
        for ( String set : models )
        {
            getLog().debug( "Preparing ruleset: " + set );
            try
            {
                File f = locator.getResourceAsFile( set, getLocationTemp( set ) );

                if ( null == f || !f.exists() )
                {
                    throw new MojoExecutionException( "Cold not resolve " + set );
                }
                if ( !f.canRead() )
                {
                    throw new MojoExecutionException( "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<String, Model> supplementMap = new HashMap<>();
        for ( Supplement sd : supplements )
        {
            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;
    }

    class OrganizationComparator
        implements Comparator<Organization>
    {
        @Override
        public int compare( Organization org1, Organization org2 )
        {
            int i = compareStrings( org1.getName(), org2.getName() );
            if ( i == 0 )
            {
                i = compareStrings( org1.getUrl(), org2.getUrl() );
            }
            return i;
        }

        public boolean equals( Organization o1, Organization o2 )
        {
            return compare( o1, o2 ) == 0;
        }

        private int compareStrings( String s1, String s2 )
        {
            if ( s1 == null && s2 == null )
            {
                return 0;
            }
            else if ( s1 == null && s2 != null )
            {
                return 1;
            }
            else if ( s1 != null && s2 == null )
            {
                return -1;
            }

            return s1.compareToIgnoreCase( s2 );
        }
    }

    class ProjectComparator
        implements Comparator<MavenProject>
    {
        @Override
        public int compare( MavenProject p1, MavenProject p2 )
        {
            return p1.getArtifact().compareTo( p2.getArtifact() );
        }

        public boolean equals( MavenProject p1, MavenProject p2 )
        {
            return p1.getArtifact().equals( p2.getArtifact() );
        }
    }

    /* LogChute methods */
    @Override
    public void init( RuntimeServices rs )
        throws Exception
    {
    }

    @Override
    public void log( int level, String message )
    {
        switch ( level )
        {
            case LogChute.WARN_ID:
                getLog().warn( message );
                break;
            case LogChute.INFO_ID:
                // velocity info messages are too verbose, just consider them as debug messages...
                getLog().debug( message );
                break;
            case LogChute.DEBUG_ID:
                getLog().debug( message );
                break;
            case LogChute.ERROR_ID:
                getLog().error( message );
                break;
            default:
                getLog().debug( message );
                break;
        }
    }

    @Override
    public void log( int level, String message, Throwable t )
    {
        switch ( level )
        {
            case LogChute.WARN_ID:
                getLog().warn( message, t );
                break;
            case LogChute.INFO_ID:
                // velocity info messages are too verbose, just consider them as debug messages...
                getLog().debug( message, t );
                break;
            case LogChute.DEBUG_ID:
                getLog().debug( message, t );
                break;
            case LogChute.ERROR_ID:
                getLog().error( message, t );
                break;
            default:
                getLog().debug( message, t );
                break;
        }
    }

    @Override
    public boolean isLevelEnabled( int level )
    {
        return false;
    }

}
