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:" + System.lineSeparator() + 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;
    }
}
