package org.apache.maven.plugins.install;

/*
 * 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.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
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.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.XmlStreamReader;
import org.codehaus.plexus.util.xml.XmlStreamWriter;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.eclipse.aether.DefaultRepositoryCache;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.ArtifactType;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.installation.InstallRequest;
import org.eclipse.aether.installation.InstallationException;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.eclipse.aether.util.artifact.SubArtifact;

/**
 * Installs a file in the local repository.
 * 
 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 */
@Mojo( name = "install-file", requiresProject = false, aggregator = true, threadSafe = true )
public class InstallFileMojo
        extends AbstractMojo
{
    private static final String LS = System.getProperty( "line.separator" );

    @Component
    private RepositorySystem repositorySystem;

    @Parameter( defaultValue = "${session}", required = true, readonly = true )
    private MavenSession session;

    /**
     * GroupId of the artifact to be installed. Retrieved from POM file if one is specified or extracted from
     * {@code pom.xml} in jar if available.
     */
    @Parameter( property = "groupId" )
    private String groupId;

    /**
     * ArtifactId of the artifact to be installed. Retrieved from POM file if one is specified or extracted from
     * {@code pom.xml} in jar if available.
     */
    @Parameter( property = "artifactId" )
    private String artifactId;

    /**
     * Version of the artifact to be installed. Retrieved from POM file if one is specified or extracted from
     * {@code pom.xml} in jar if available.
     */
    @Parameter( property = "version" )
    private String version;

    /**
     * Packaging type of the artifact to be installed. Retrieved from POM file if one is specified or extracted from
     * {@code pom.xml} in jar if available.
     */
    @Parameter( property = "packaging" )
    private String packaging;

    /**
     * Classifier type of the artifact to be installed. For example, "sources" or "javadoc". Defaults to none which
     * means this is the project's main artifact.
     * 
     * @since 2.2
     */
    @Parameter( property = "classifier" )
    private String classifier;

    /**
     * The file to be installed in the local repository.
     */
    @Parameter( property = "file", required = true )
    private File file;

    /**
     * The bundled API docs for the artifact.
     * 
     * @since 2.3
     */
    @Parameter( property = "javadoc" )
    private File javadoc;

    /**
     * The bundled sources for the artifact.
     * 
     * @since 2.3
     */
    @Parameter( property = "sources" )
    private File sources;

    /**
     * Location of an existing POM file to be installed alongside the main artifact, given by the {@link #file}
     * parameter.
     * 
     * @since 2.1
     */
    @Parameter( property = "pomFile" )
    private File pomFile;

    /**
     * Generate a minimal POM for the artifact if none is supplied via the parameter {@link #pomFile}. Defaults to
     * <code>true</code> if there is no existing POM in the local repository yet.
     * 
     * @since 2.1
     */
    @Parameter( property = "generatePom" )
    private Boolean generatePom;

    /**
     * The path for a specific local repository directory. If not specified the local repository path configured in the
     * Maven settings will be used.
     * 
     * @since 2.2
     */
    @Parameter( property = "localRepositoryPath" )
    private File localRepositoryPath;

    @Override
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        if ( !file.exists() )
        {
            String message = "The specified file '" + file.getPath() + "' does not exist";
            getLog().error( message );
            throw new MojoFailureException( message );
        }

        RepositorySystemSession repositorySystemSession = session.getRepositorySession();
        if ( localRepositoryPath != null )
        {
            // "clone" repository session and replace localRepository
            DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession(
                    session.getRepositorySession() );
            // Clear cache, since we're using a new local repository
            newSession.setCache( new DefaultRepositoryCache() );
            // keep same repositoryType
            String contentType = newSession.getLocalRepository().getContentType();
            if ( "enhanced".equals( contentType ) )
            {
                contentType = "default";
            }
            LocalRepositoryManager localRepositoryManager = repositorySystem.newLocalRepositoryManager( newSession,
                    new LocalRepository( localRepositoryPath, contentType ) );
            newSession.setLocalRepositoryManager( localRepositoryManager );
            repositorySystemSession = newSession;
            getLog().debug( "localRepoPath: " + localRepositoryManager.getRepository().getBasedir() );
        }

        File temporaryPom = null;

        if ( pomFile != null )
        {
            processModel( readModel( pomFile ) );
        }
        else
        {
            temporaryPom = readingPomFromJarFile();
            pomFile = temporaryPom;
        }

        if ( groupId == null || artifactId == null || version == null || packaging == null )
        {
            throw new MojoExecutionException( "The artifact information is incomplete: 'groupId', 'artifactId', "
                    + "'version' and 'packaging' are required." );
        }

        if ( !isValidId( groupId )
                || !isValidId( artifactId )
                || !isValidVersion( version ) )
        {
            throw new MojoExecutionException( "The artifact information is not valid: uses invalid characters." );
        }

        InstallRequest installRequest = new InstallRequest();

        boolean isFilePom = classifier == null && "pom".equals( packaging );
        if ( !isFilePom )
        {
            ArtifactType artifactType = repositorySystemSession.getArtifactTypeRegistry().get( packaging );
            if ( artifactType != null
                    && StringUtils.isEmpty( classifier )
                    && !StringUtils.isEmpty( artifactType.getClassifier() ) )
            {
                classifier = artifactType.getClassifier();
            }
        }
        Artifact mainArtifact = new DefaultArtifact(
                groupId,
                artifactId,
                classifier,
                isFilePom ? "pom" : getExtension( file ),
                version
        ).setFile( file );
        installRequest.addArtifact( mainArtifact );

        File artifactLocalFile = getLocalRepositoryFile( session.getRepositorySession(), mainArtifact );
        File pomLocalFile = getPomLocalRepositoryFile( session.getRepositorySession(), mainArtifact );

        if ( file.equals( artifactLocalFile ) )
        {
            throw new MojoFailureException( "Cannot install artifact. "
                + "Artifact is already in the local repository." + LS + LS + "File in question is: " + file + LS );
        }

        if ( !"pom".equals( packaging ) )
        {
            if ( pomFile != null )
            {
                installRequest.addArtifact( new SubArtifact( mainArtifact, "", "pom", pomFile ) );
            }
            else
            {
                if ( Boolean.TRUE.equals( generatePom ) || ( generatePom == null && !pomLocalFile.exists() ) )
                {
                    temporaryPom = generatePomFile();
                    getLog().debug( "Installing generated POM" );
                    installRequest.addArtifact( new SubArtifact( mainArtifact, "", "pom", temporaryPom ) );
                }
                else if ( generatePom == null )
                {
                    getLog().debug( "Skipping installation of generated POM, already present in local repository" );
                }
            }
        }

        if ( sources != null )
        {
            installRequest.addArtifact( new SubArtifact( mainArtifact, "sources", "jar", sources ) );
        }

        if ( javadoc != null )
        {
            installRequest.addArtifact( new SubArtifact( mainArtifact, "javadoc", "jar", javadoc ) );
        }

        try
        {
            repositorySystem.install( repositorySystemSession, installRequest );
        }
        catch ( InstallationException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
        finally
        {
            if ( temporaryPom != null )
            {
                // noinspection ResultOfMethodCallIgnored
                temporaryPom.delete();
            }
        }
    }

    private File readingPomFromJarFile()
        throws MojoExecutionException
    {
        File pomFile = null;

        JarFile jarFile = null;
        try
        {
            Pattern pomEntry = Pattern.compile( "META-INF/maven/.*/pom\\.xml" );

            jarFile = new JarFile( file );

            Enumeration<JarEntry> jarEntries = jarFile.entries();

            while ( jarEntries.hasMoreElements() )
            {
                JarEntry entry = jarEntries.nextElement();

                if ( pomEntry.matcher( entry.getName() ).matches() )
                {
                    getLog().debug( "Using " + entry.getName() + " as pomFile" );

                    InputStream pomInputStream = null;
                    OutputStream pomOutputStream = null;

                    try
                    {
                        pomInputStream = jarFile.getInputStream( entry );

                        String base = file.getName();
                        if ( base.indexOf( '.' ) > 0 )
                        {
                            base = base.substring( 0, base.lastIndexOf( '.' ) );
                        }
                        pomFile = File.createTempFile( base, ".pom" );

                        pomOutputStream = Files.newOutputStream( pomFile.toPath() );

                        IOUtil.copy( pomInputStream, pomOutputStream );

                        pomOutputStream.close();
                        pomOutputStream = null;

                        pomInputStream.close();
                        pomInputStream = null;

                        processModel( readModel( pomFile ) );

                        break;
                    }
                    finally
                    {
                        IOUtil.close( pomInputStream );
                        IOUtil.close( pomOutputStream );
                    }
                }
            }

            if ( pomFile == null )
            {
                getLog().info( "pom.xml not found in " + file.getName() );
            }
        }
        catch ( IOException e )
        {
            // ignore, artifact not packaged by Maven
        }
        finally
        {
            if ( jarFile != null )
            {
                try
                {
                    jarFile.close();
                }
                catch ( IOException e )
                {
                    // we did our best
                }
            }
        }
        return pomFile;
    }

    /**
     * Parses a POM.
     * 
     * @param pomFile The path of the POM file to parse, must not be <code>null</code>.
     * @return The model from the POM file, never <code>null</code>.
     * @throws MojoExecutionException If the POM could not be parsed.
     */
    private Model readModel( File pomFile )
        throws MojoExecutionException
    {
        Reader reader = null;
        try
        {
            reader = new XmlStreamReader( pomFile );
            final Model model = new MavenXpp3Reader().read( reader );
            reader.close();
            reader = null;
            return model;
        }
        catch ( FileNotFoundException e )
        {
            throw new MojoExecutionException( "File not found " + pomFile, e );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Error reading POM " + pomFile, e );
        }
        catch ( XmlPullParserException e )
        {
            throw new MojoExecutionException( "Error parsing POM " + pomFile, e );
        }
        finally
        {
            IOUtil.close( reader );
        }
    }

    /**
     * Populates missing mojo parameters from the specified POM.
     * 
     * @param model The POM to extract missing artifact coordinates from, must not be <code>null</code>.
     */
    private void processModel( Model model )
    {
        Parent parent = model.getParent();

        if ( this.groupId == null )
        {
            this.groupId = model.getGroupId();
            if ( this.groupId == null && parent != null )
            {
                this.groupId = parent.getGroupId();
            }
        }
        if ( this.artifactId == null )
        {
            this.artifactId = model.getArtifactId();
        }
        if ( this.version == null )
        {
            this.version = model.getVersion();
            if ( this.version == null && parent != null )
            {
                this.version = parent.getVersion();
            }
        }
        if ( this.packaging == null )
        {
            this.packaging = model.getPackaging();
        }
    }

    /**
     * Generates a minimal model from the user-supplied artifact information.
     * 
     * @return The generated model, never <code>null</code>.
     */
    private Model generateModel()
    {
        Model model = new Model();

        model.setModelVersion( "4.0.0" );

        model.setGroupId( groupId );
        model.setArtifactId( artifactId );
        model.setVersion( version );
        model.setPackaging( packaging );

        model.setDescription( "POM was created from install:install-file" );

        return model;
    }

    /**
     * Generates a (temporary) POM file from the plugin configuration. It's the responsibility of the caller to delete
     * the generated file when no longer needed.
     * 
     * @return The path to the generated POM file, never <code>null</code>.
     * @throws MojoExecutionException If the POM file could not be generated.
     */
    private File generatePomFile()
        throws MojoExecutionException
    {
        Model model = generateModel();

        Writer writer = null;
        try
        {
            File pomFile = File.createTempFile( "mvninstall", ".pom" );

            writer = new XmlStreamWriter( pomFile );
            new MavenXpp3Writer().write( writer, model );
            writer.close();
            writer = null;

            return pomFile;
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Error writing temporary POM file: " + e.getMessage(), e );
        }
        finally
        {
            IOUtil.close( writer );
        }
    }

    /**
     * Gets the path of the specified artifact within the local repository. Note that the returned path need not exist
     * (yet).
     */
    private File getLocalRepositoryFile( RepositorySystemSession session, Artifact artifact )
    {
        String path = session.getLocalRepositoryManager().getPathForLocalArtifact( artifact );
        return new File( session.getLocalRepository().getBasedir(), path );
    }

    /**
     * Gets the path of the specified artifact POM within the local repository. Note that the returned path need
     * not exist (yet).
     */
    private File getPomLocalRepositoryFile( RepositorySystemSession session, Artifact artifact )
    {
        SubArtifact pomArtifact = new SubArtifact( artifact, "", "pom" );
        String path = session.getLocalRepositoryManager().getPathForLocalArtifact( pomArtifact );
        return new File( session.getLocalRepository().getBasedir(), path );
    }

    // these below should be shared (duplicated in m-install-p, m-deploy-p)

    /**
     * Specialization of {@link FileUtils#getExtension(String)} that honors various {@code tar.xxx} combinations.
     */
    private String getExtension( final File file )
    {
        String filename = file.getName();
        if ( filename.contains( ".tar." ) )
        {
            return "tar." + FileUtils.getExtension( filename );
        }
        else
        {
            return FileUtils.getExtension( filename );
        }
    }

    /**
     * Returns {@code true} if passed in string is "valid Maven ID" (groupId or artifactId).
     */
    private boolean isValidId( String id )
    {
        if ( id == null )
        {
            return false;
        }
        for ( int i = 0; i < id.length(); i++ )
        {
            char c = id.charAt( i );
            if ( !( c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'
                    || c >= '0' && c <= '9' || c == '-' || c == '_' || c == '.' ) )
            {
                return false;
            }
        }
        return true;
    }

    private static final String ILLEGAL_VERSION_CHARS = "\\/:\"<>|?*[](){},";

    /**
     * Returns {@code true} if passed in string is "valid Maven (simple. non range, expression, etc) version".
     */
    private boolean isValidVersion( String version )
    {
        if ( version == null )
        {
            return false;
        }
        for ( int i = version.length() - 1; i >= 0; i-- )
        {
            if ( ILLEGAL_VERSION_CHARS.indexOf( version.charAt( i ) ) >= 0 )
            {
                return false;
            }
        }
        return true;
    }

}
