package org.apache.maven.plugins.repository;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.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.model.License;
import org.apache.maven.model.Model;
import org.apache.maven.model.Scm;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.jar.JarArchiver;
import org.codehaus.plexus.components.interactivity.InputHandler;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.plexus.util.xml.XmlStreamReader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * Packs artifacts already available in a local repository in a bundle for an
 * upload requests. It requires that the artifact has a POM in the local
 * repository. It will check for mandatory elements, asking interactively for
 * missing values. Can be used to generate bundles for third parties artifacts
 * that have been manually added to the local repository.
 *
 * @since 2.1
 */
@Mojo( name = "bundle-pack", requiresProject = false )
public class BundlePackMojo
    extends AbstractMojo
{
    public static final String POM = "pom.xml";

    /**
     * Jar archiver.
     */
    @Component( role = Archiver.class, hint = "jar" )
    protected JarArchiver jarArchiver;

    /**
     * Artifact resolver.
     */
    @Component
    protected ArtifactResolver artifactResolver;

    /**
     * Artifact factory.
     */
    @Component
    protected ArtifactFactory artifactFactory;

    /**
     * Local maven repository.
     */
    @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
    protected ArtifactRepository localRepository;

    /**
     */
    @Component
    protected InputHandler inputHandler;

    /**
     * Directory where the upload-bundle will be created.
     */
    @Parameter( defaultValue = "${basedir}", readonly = true )
    protected String basedir;

    /**
     * GroupId for the artifact to create an upload bundle for.
     */
    @Parameter( property = "groupId" )
    protected String groupId;

    /**
     * ArtifactId for the artifact to create an upload bundle for.
     */
    @Parameter( property = "artifactId" )
    protected String artifactId;

    /**
     * Version for the artifact to create an upload bundle for.
     */
    @Parameter( property = "version" )
    protected String version;

    /**
     * Viewable URL for SCM connections, in cases where this isn't provided by the POM.
     */
    @Parameter( property = "scmUrl" )
    protected String scmUrl;

    /**
     * Read-only URL for SCM tool connections, in cases where this isn't provided by the POM.
     * <br/>
     * <b>NOTE:</b> This should be a standard maven-scm URL. See the
     * <a href="http://maven.apache.org/scm/scm-url-format.html">format guidelines</a> for more
     * information.
     */
    @Parameter( property = "scmConnection" )
    protected String scmConnection;

    /**
     */
    @Parameter( defaultValue = "${settings}", readonly = true, required = true )
    protected Settings settings;

    /**
     * Disable validations to make sure bundle supports project materialization.
     * <br/>
     * <b>WARNING: This means your project will be MUCH harder to use.</b>
     */
    @Parameter( property = "bundle.disableMaterialization", defaultValue = "false" )
    private boolean disableMaterialization;

    @SuppressWarnings( "unchecked" )
    public void execute()
        throws MojoExecutionException
    {
        readArtifactDataFromUser();

        Artifact artifact = artifactFactory.createProjectArtifact( groupId, artifactId, version );

        try
        {
            artifactResolver.resolve( artifact, Collections.EMPTY_LIST, localRepository );
        }
        catch ( ArtifactResolutionException e )
        {
            throw new MojoExecutionException( "Unable to resolve artifact " + artifact.getId(), e );
        }
        catch ( ArtifactNotFoundException e )
        {
            throw new MojoExecutionException( "Artifact " + artifact.getId() + " not found in local repository", e );
        }

        File pom = artifact.getFile();

        File dir = pom.getParentFile();

        Model model = readPom( pom );

        boolean rewrite = false;
        try
        {

            if ( model.getPackaging() == null )
            {
                model.setPackaging( "jar" );
                rewrite = true;
            }
            if ( model.getName() == null )
            {
                getLog().info( "Project name is missing, please type the project name [" + artifactId + "]:" );
                model.setName( inputHandler.readLine() );
                if ( model.getName() == null )
                {
                    model.setName( artifactId );
                }
                rewrite = true;
            }
            if ( model.getDescription() == null )
            {
                getLog().info( "Project description is missing, please type the project description:" );
                model.setDescription( inputHandler.readLine() );
                rewrite = true;
            }
            if ( model.getUrl() == null )
            {
                getLog().info( "Project URL is missing, please type the project URL:" );
                model.setUrl( inputHandler.readLine() );
                rewrite = true;
            }

            List<License> licenses = model.getLicenses();
            if ( licenses.isEmpty() )
            {
                License license = new License();

                getLog().info( "License name is missing, please type the license name:" );
                license.setName( inputHandler.readLine() );
                getLog().info( "License URL is missing, please type the license URL:" );
                license.setUrl( inputHandler.readLine() );
                licenses.add( license );
                rewrite = true;
            }

            if ( disableMaterialization )
            {
                getLog().warn( "Validations to confirm support for project materialization have been DISABLED."
                                   + "\n\nYour project may not provide the POM elements necessary to allow "
                                   + "users to retrieve sources on-demand,"
                                   + "\nor to easily checkout your project in an IDE. "
                                   + "THIS CAN SERIOUSLY INCONVENIENCE YOUR USERS.\n\nContinue? [y/N]" );

                try
                {
                    if ( 'y' != inputHandler.readLine()
                                            .toLowerCase()
                                            .charAt( 0 ) )
                    {
                        disableMaterialization = false;
                    }
                }
                catch ( IOException e )
                {
                    getLog().debug( "Error reading confirmation: " + e.getMessage(), e );
                }

            }

            if ( !disableMaterialization )
            {
                Scm scm = model.getScm();
                if ( scm == null )
                {
                    scm = new Scm();
                    model.setScm( scm );
                }

                if ( scm.getUrl() == null )
                {
                    if ( scmUrl != null )
                    {
                        scm.setUrl( scmUrl );
                    }
                    else
                    {
                        getLog().info( "SCM view URL is missing, please type the URL for the viewable SCM interface:" );
                        scm.setUrl( inputHandler.readLine() );
                        rewrite = true;
                    }
                }

                if ( scm.getConnection() == null )
                {
                    if ( scmConnection != null )
                    {
                        scm.setConnection( scmConnection );
                    }
                    else
                    {
                        getLog().info( "SCM read-only connection URL is missing, please type the read-only SCM URL:" );
                        scm.setConnection( inputHandler.readLine() );
                        rewrite = true;
                    }
                }
            }
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }

        try
        {
            if ( rewrite )
            {
                new MavenXpp3Writer().write( WriterFactory.newXmlWriter( pom ), model );
            }

            String finalName = null;

            if ( model.getBuild() != null )
            {
                finalName = model.getBuild()
                                 .getFinalName();
            }
            if ( finalName == null )
            {
                finalName = model.getArtifactId() + "-" + model.getVersion();
            }

            boolean batchMode = settings == null ? false : !settings.isInteractiveMode();
            List<File> files = BundleUtils.selectProjectFiles( dir, inputHandler, finalName, pom, getLog(), batchMode );

            File bundle = new File( basedir, finalName + "-bundle.jar" );

            jarArchiver.addFile( pom, POM );

            boolean artifactChecks = !"pom".equals( model.getPackaging() );
            boolean sourcesFound = false;
            boolean javadocsFound = false;

            for ( File f : files )
            {
                if ( artifactChecks && f.getName()
                                        .endsWith( finalName + "-sources.jar" ) )
                {
                    sourcesFound = true;
                }
                else if ( artifactChecks && f.getName()
                                             .equals( finalName + "-javadoc.jar" ) )
                {
                    javadocsFound = true;
                }

                jarArchiver.addFile( f, f.getName() );
            }

            if ( artifactChecks && !sourcesFound )
            {
                getLog().warn( "Sources not included in upload bundle." );
            }

            if ( artifactChecks && !javadocsFound )
            {
                getLog().warn( "Javadoc not included in upload bundle." );
            }

            jarArchiver.setDestFile( bundle );

            jarArchiver.createArchive();

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

    }

    /**
     * Read groupId, artifactId and version from the user on the command line,
     * if they were not provided as parameters.
     *
     * @throws MojoExecutionException If the values can't be read
     */
    private void readArtifactDataFromUser()
        throws MojoExecutionException
    {
        try
        {
            if ( groupId == null )
            {
                getLog().info( "groupId? " );

                groupId = inputHandler.readLine();

            }

            if ( artifactId == null )
            {
                getLog().info( "artifactId? " );
                artifactId = inputHandler.readLine();
            }

            if ( version == null )
            {
                getLog().info( "version? " );
                version = inputHandler.readLine();
            }
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
    }

    /**
     * Read the POM file.
     *
     * @param pom The file to read
     * @return A Maven Model
     * @throws MojoExecutionException if something goes wrong when reading the file
     */
    private Model readPom( File pom )
        throws MojoExecutionException
    {
        Model model;
        XmlStreamReader reader = null;
        try
        {
            reader = ReaderFactory.newXmlReader( pom );
            model = new MavenXpp3Reader().read( reader );
            reader.close();
            reader = null;
        }
        catch ( XmlPullParserException e )
        {
            throw new MojoExecutionException( "Unable to parse POM at " + pom.getAbsolutePath() + ": " + e.getMessage(),
                                              e );
        }
        catch ( FileNotFoundException e )
        {
            throw new MojoExecutionException( "Unable to read POM at " + pom.getAbsolutePath() + ": " + e.getMessage(),
                                              e );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Unable to read POM at " + pom.getAbsolutePath() + ": " + e.getMessage(),
                                              e );
        }
        finally
        {
            IOUtil.close( reader );
        }
        return model;
    }

}
