package org.apache.maven.plugins.dependency.fromDependencies;

/*
 * 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.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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.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.plugins.dependency.utils.DependencyUtil;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter;
import org.apache.maven.shared.transfer.repository.RepositoryManager;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;

/**
 * This goal will output a classpath string of dependencies from the local repository to a file or log.
 *
 * @author ankostis
 * @since 2.0-alpha-2
 */
// CHECKSTYLE_OFF: LineLength
@Mojo( name = "build-classpath", requiresDependencyResolution = ResolutionScope.TEST, defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true )
// CHECKSTYLE_ON: LineLength
public class BuildClasspathMojo
    extends AbstractDependencyFilterMojo
    implements Comparator<Artifact>
{

    /**
     * Strip artifact version during copy (only works if prefix is set)
     */
    @Parameter( property = "mdep.stripVersion", defaultValue = "false" )
    private boolean stripVersion = false;

    /**
     * Strip artifact classifier during copy (only works if prefix is set)
     */
    @Parameter( property = "mdep.stripClassifier", defaultValue = "false" )
    private boolean stripClassifier = false;

    /**
     * The prefix to prepend on each dependent artifact. If undefined, the paths refer to the actual files store in the
     * local repository (the stripVersion parameter does nothing then).
     */
    @Parameter( property = "mdep.prefix" )
    private String prefix;

    /**
     * A property to set to the content of the classpath string.
     */
    @Parameter( property = "mdep.outputProperty" )
    private String outputProperty;

    /**
     * The file to write the classpath string. If undefined, it just prints the classpath as [INFO].
     */
    @Parameter( property = "mdep.outputFile" )
    private File outputFile;

    /**
     * If 'true', it skips the up-to-date-check, and always regenerates the classpath file.
     */
    @Parameter( property = "mdep.regenerateFile", defaultValue = "false" )
    private boolean regenerateFile;

    /**
     * Override the char used between the paths. This field is initialized to contain the first character of the value
     * of the system property file.separator. On UNIX systems the value of this field is '/'; on Microsoft Windows
     * systems it is '\'. The default is File.separator
     *
     * @since 2.0
     */
    @Parameter( property = "mdep.fileSeparator", defaultValue = "" )
    private String fileSeparator;

    /**
     * Override the char used between path folders. The system-dependent path-separator character. This field is
     * initialized to contain the first character of the value of the system property path.separator. This character is
     * used to separate filenames in a sequence of files given as a path list. On UNIX systems, this character is ':';
     * on Microsoft Windows systems it is ';'.
     *
     * @since 2.0
     */
    @Parameter( property = "mdep.pathSeparator", defaultValue = "" )
    private String pathSeparator;

    /**
     * Replace the absolute path to the local repo with this property. This field is ignored it prefix is declared. The
     * value will be forced to "${M2_REPO}" if no value is provided AND the attach flag is true.
     *
     * @since 2.0
     */
    @Parameter( property = "mdep.localRepoProperty", defaultValue = "" )
    private String localRepoProperty;

    /**
     * Attach the classpath file to the main artifact so it can be installed and deployed.
     *
     * @since 2.0
     */
    @Parameter( defaultValue = "false" )
    private boolean attach;

    /**
     * Write out the classpath in a format compatible with filtering (classpath=xxxxx)
     *
     * @since 2.0
     */
    @Parameter( property = "mdep.outputFilterFile", defaultValue = "false" )
    private boolean outputFilterFile;

    /**
     * Either append the artifact's baseVersion or uniqueVersion to the filename. Will only be used if
     * {@link #isStripVersion()} is {@code false}.
     * 
     * @since 2.6
     */
    @Parameter( property = "mdep.useBaseVersion", defaultValue = "true" )
    private boolean useBaseVersion = true;

    /**
     * Maven ProjectHelper
     */
    @Component
    private MavenProjectHelper projectHelper;

    @Component
    private RepositoryManager repositoryManager;

    /**
     * Main entry into mojo. Gets the list of dependencies and iterates to create a classpath.
     *
     * @throws MojoExecutionException with a message if an error occurs.
     * @see #getResolvedDependencies(boolean)
     */
    @Override
    protected void doExecute()
        throws MojoExecutionException
    {
        // initialize the separators.
        boolean isFileSepSet = StringUtils.isNotEmpty( fileSeparator );
        boolean isPathSepSet = StringUtils.isNotEmpty( pathSeparator );

        // don't allow them to have absolute paths when they attach.
        if ( attach && StringUtils.isEmpty( localRepoProperty ) )
        {
            localRepoProperty = "${M2_REPO}";
        }

        Set<Artifact> artifacts = getResolvedDependencies( true );

        if ( artifacts == null || artifacts.isEmpty() )
        {
            getLog().info( "No dependencies found." );
        }

        List<Artifact> artList = new ArrayList<Artifact>( artifacts );

        StringBuilder sb = new StringBuilder();
        Iterator<Artifact> i = artList.iterator();

        if ( i.hasNext() )
        {
            appendArtifactPath( i.next(), sb );

            while ( i.hasNext() )
            {
                sb.append( isPathSepSet ? this.pathSeparator : File.pathSeparator );
                appendArtifactPath( i.next(), sb );
            }
        }

        String cpString = sb.toString();

        // if file separator is set, I need to replace the default one from all
        // the file paths that were pulled from the artifacts
        if ( isFileSepSet )
        {
            // Escape file separators to be used as literal strings
            final String pattern = Pattern.quote( File.separator );
            final String replacement = Matcher.quoteReplacement( fileSeparator );
            cpString = cpString.replaceAll( pattern, replacement );
        }

        // make the string valid for filtering
        if ( outputFilterFile )
        {
            cpString = "classpath=" + cpString;
        }

        if ( outputProperty != null )
        {
            getProject().getProperties().setProperty( outputProperty, cpString );
            if ( getLog().isDebugEnabled() )
            {
                getLog().debug( outputProperty + " = " + cpString );
            }
        }

        if ( outputFile == null )
        {
            getLog().info( "Dependencies classpath:\n" + cpString );
        }
        else
        {
            if ( regenerateFile || !isUpdToDate( cpString ) )
            {
                storeClasspathFile( cpString, outputFile );
            }
            else
            {
                this.getLog().info( "Skipped writing classpath file '" + outputFile + "'.  No changes found." );
            }
        }
        if ( attach )
        {
            attachFile( cpString );
        }
    }

    /**
     * @param cpString The classpath.
     * @throws MojoExecutionException in case of an error.
     */
    protected void attachFile( String cpString )
        throws MojoExecutionException
    {
        File attachedFile = new File( getProject().getBuild().getDirectory(), "classpath" );
        storeClasspathFile( cpString, attachedFile );

        projectHelper.attachArtifact( getProject(), attachedFile, "classpath" );
    }

    /**
     * Appends the artifact path into the specified StringBuilder.
     *
     * @param art {@link Artifact}
     * @param sb {@link StringBuilder}
     */
    protected void appendArtifactPath( Artifact art, StringBuilder sb )
    {
        if ( prefix == null )
        {
            String file = art.getFile().getPath();
            // substitute the property for the local repo path to make the classpath file portable.
            if ( StringUtils.isNotEmpty( localRepoProperty ) )
            {
                File localBasedir = repositoryManager.getLocalRepositoryBasedir( session.getProjectBuildingRequest() );

                file = StringUtils.replace( file, localBasedir.getAbsolutePath(), localRepoProperty );
            }
            sb.append( file );
        }
        else
        {
            // TODO: add param for prepending groupId and version.
            sb.append( prefix );
            sb.append( File.separator );
            sb.append( DependencyUtil.getFormattedFileName( art, this.stripVersion, this.prependGroupId,
                                                            this.useBaseVersion, this.stripClassifier ) );
        }
    }

    /**
     * Checks that new classpath differs from that found inside the old classpathFile.
     *
     * @param cpString
     * @return true if the specified classpath equals to that found inside the file, false otherwise (including when
     *         file does not exists but new classpath does).
     */
    private boolean isUpdToDate( String cpString )
    {
        try
        {
            String oldCp = readClasspathFile();
            return ( cpString == null ? oldCp == null : cpString.equals( oldCp ) );
        }
        catch ( Exception ex )
        {
            this.getLog().warn( "Error while reading old classpath file '" + outputFile + "' for up-to-date check: "
                + ex );

            return false;
        }
    }

    /**
     * It stores the specified string into that file.
     *
     * @param cpString the string to be written into the file.
     * @throws MojoExecutionException
     */
    private void storeClasspathFile( String cpString, File out )
        throws MojoExecutionException
    {
        // make sure the parent path exists.
        out.getParentFile().mkdirs();

        Writer w = null;
        try
        {
            w = new BufferedWriter( new FileWriter( out ) );
            w.write( cpString );
            w.close();
            w = null;
            getLog().info( "Wrote classpath file '" + out + "'." );
        }
        catch ( IOException ex )
        {
            throw new MojoExecutionException( "Error while writting to classpath file '" + out + "': " + ex.toString(),
                                              ex );
        }
        finally
        {
            IOUtil.close( w );
        }
    }

    /**
     * Reads into a string the file specified by the mojo param 'outputFile'. Assumes, the instance variable
     * 'outputFile' is not null.
     * 
     * @return the string contained in the classpathFile, if exists, or null otherwise.
     * @throws IOException in case of an error.
     */
    protected String readClasspathFile()
        throws IOException
    {
        if ( outputFile == null )
        {
            throw new IllegalArgumentException( "The outputFile parameter "
                + "cannot be null if the file is intended to be read." );
        }

        if ( !outputFile.isFile() )
        {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        BufferedReader r = null;

        try
        {
            r = new BufferedReader( new FileReader( outputFile ) );

            for ( String line = r.readLine(); line != null; line = r.readLine() )
            {
                sb.append( line );
            }

            r.close();
            r = null;

            return sb.toString();
        }
        finally
        {
            IOUtil.close( r );
        }
    }

    /**
     * Compares artifacts lexicographically, using pattern [group_id][artifact_id][version].
     *
     * @param art1 first object
     * @param art2 second object
     * @return the value <code>0</code> if the argument string is equal to this string; a value less than <code>0</code>
     *         if this string is lexicographically less than the string argument; and a value greater than
     *         <code>0</code> if this string is lexicographically greater than the string argument.
     */
    @Override
    public int compare( Artifact art1, Artifact art2 )
    {
        if ( art1 == art2 )
        {
            return 0;
        }
        else if ( art1 == null )
        {
            return -1;
        }
        else if ( art2 == null )
        {
            return +1;
        }

        String s1 = art1.getGroupId() + art1.getArtifactId() + art1.getVersion();
        String s2 = art2.getGroupId() + art2.getArtifactId() + art2.getVersion();

        return s1.compareTo( s2 );
    }

    @Override
    protected ArtifactsFilter getMarkedArtifactFilter()
    {
        return null;
    }

    /**
     * @param outputFile the outputFile to set
     */
    public void setOutputFile( File outputFile )
    {
        this.outputFile = outputFile;
    }

    /**
     * @param theOutputProperty the outputProperty to set
     */
    public void setOutputProperty( String theOutputProperty )
    {
        this.outputProperty = theOutputProperty;
    }

    /**
     * @param theFileSeparator the fileSeparator to set
     */
    public void setFileSeparator( String theFileSeparator )
    {
        this.fileSeparator = theFileSeparator;
    }

    /**
     * @param thePathSeparator the pathSeparator to set
     */
    public void setPathSeparator( String thePathSeparator )
    {
        this.pathSeparator = thePathSeparator;
    }

    /**
     * @param thePrefix the prefix to set
     */
    public void setPrefix( String thePrefix )
    {
        this.prefix = thePrefix;
    }

    /**
     * @param theRegenerateFile the regenerateFile to set
     */
    public void setRegenerateFile( boolean theRegenerateFile )
    {
        this.regenerateFile = theRegenerateFile;
    }

    /**
     * @return the stripVersion
     */
    public boolean isStripVersion()
    {
        return this.stripVersion;
    }

    /**
     * @param theStripVersion the stripVersion to set
     */
    public void setStripVersion( boolean theStripVersion )
    {
        this.stripVersion = theStripVersion;
    }

    /**
     * @param localRepoProperty {@link #localRepoProperty}
     */
    public void setLocalRepoProperty( String localRepoProperty )
    {
        this.localRepoProperty = localRepoProperty;
    }
}
