package org.apache.maven.plugins.release;

/*
 * 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.nio.file.Path;
import java.util.Iterator;
import java.util.List;

import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.apache.maven.shared.release.ReleaseManager;
import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder;
import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
import org.apache.maven.shared.release.env.ReleaseEnvironment;
import org.codehaus.plexus.util.StringUtils;

/**
 * Base class with shared configuration.
 *
 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 * @version $Id$
 */
public abstract class AbstractReleaseMojo
    extends AbstractMojo
{
    /**
     */
    @Parameter( defaultValue = "${basedir}", readonly = true, required = true )
    private File basedir;

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

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

    /**
     */
    @Component
    protected ReleaseManager releaseManager;

    /**
     * Additional arguments to pass to the Maven executions, separated by spaces.
     */
    @Parameter( alias = "prepareVerifyArgs", property = "arguments" )
    private String arguments;

    /**
     * The file name of the POM to execute any goals against. As of version 3.0.0, this defaults to the name of
     * POM file of the project being built.
     */
    @Parameter( property = "pomFileName", defaultValue = "${project.file.name}" )
    private String pomFileName;

    /**
     */
    @Parameter( defaultValue = "${reactorProjects}", readonly = true, required = true )
    private List<MavenProject> reactorProjects;

    /**
     * The {@code M2_HOME} parameter to use for forked Maven invocations.
     *
     * @since 2.0-beta-8
     */
    @Parameter( defaultValue = "${maven.home}" )
    private File mavenHome;

    /**
     * The {@code JAVA_HOME} parameter to use for forked Maven invocations.
     *
     * @since 2.0-beta-8
     */
    @Parameter( defaultValue = "${java.home}" )
    private File javaHome;

    /**
     * The command-line local repository directory in use for this build (if specified).
     *
     * @since 2.0-beta-8
     */
    @Parameter ( defaultValue = "${maven.repo.local}" )
    private File localRepoDirectory;

    /**
     * Role hint of the {@link org.apache.maven.shared.release.exec.MavenExecutor} implementation to use.
     *
     * @since 2.0-beta-8
     */
    @Parameter( defaultValue = "invoker", property = "mavenExecutorId" )
    private String mavenExecutorId;

    /**
     * @since 2.0
     */
    @Parameter( defaultValue = "${session}", readonly = true, required = true )
    protected MavenSession session;

    /**
     * The role-hint for the {@link org.apache.maven.shared.release.strategy.Strategy}
     * implementation used to specify the phases per goal.
     * 
     * @since 3.0.0
     * @see org.apache.maven.shared.release.strategies.DefaultStrategy
     */
    @Parameter( defaultValue = "default", property = "releaseStrategyId" )
    private String releaseStrategyId;
    
    /**
     * Gets the enviroment settings configured for this release.
     *
     * @return The release environment, never <code>null</code>.
     */
    protected ReleaseEnvironment getReleaseEnvironment()
    {
        return new DefaultReleaseEnvironment().setSettings( settings )
                                              .setJavaHome( javaHome )
                                              .setMavenHome( mavenHome )
                                              .setLocalRepositoryDirectory( localRepoDirectory )
                                              .setMavenExecutorId( mavenExecutorId );
    }

    /**
     * Creates the release descriptor from the various goal parameters.
     *
     * @return The release descriptor, never <code>null</code>.
     */
    protected ReleaseDescriptorBuilder createReleaseDescriptor()
    {
        ReleaseDescriptorBuilder descriptor = new ReleaseDescriptorBuilder();
        
        descriptor.setInteractive( settings.isInteractiveMode() );

        Path workingDirectory;
        if ( reactorProjects == null || reactorProjects.size() <= 1 )
        {
            workingDirectory = basedir.toPath();
        }
        else
        {
            workingDirectory = getCommonBasedir( reactorProjects );
        }
        descriptor.setWorkingDirectory( workingDirectory.toFile().getAbsolutePath() );

        Path rootBasedir = basedir.toPath();
        if ( rootBasedir.equals( workingDirectory ) )
        {
            descriptor.setPomFileName( pomFileName );
        }
        else
        {
            descriptor.setPomFileName( workingDirectory.relativize( rootBasedir ).resolve( pomFileName ).toString() );
        }

        for ( MavenProject project : reactorProjects )
        {
            String versionlessKey = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
            descriptor.putOriginalVersion( versionlessKey, project.getVersion() );
            
            if ( project.getFile() != null )
            {
                descriptor.addProjectPomFile( versionlessKey,
                                              workingDirectory.relativize( project.getFile().toPath() ).toString() );
            }
        }

        List<String> profileIds = session.getRequest().getActiveProfiles();
        String additionalProfiles = getAdditionalProfiles();

        String args = this.arguments;
        if ( !profileIds.isEmpty() || StringUtils.isNotBlank( additionalProfiles ) )
        {
            if ( !StringUtils.isEmpty( args ) )
            {
                args += " -P ";
            }
            else
            {
                args = "-P ";
            }

            for ( Iterator<String> it = profileIds.iterator(); it.hasNext(); )
            {
                args += it.next();
                if ( it.hasNext() )
                {
                    args += ",";
                }
            }

            if ( additionalProfiles != null )
            {
                if ( !profileIds.isEmpty() )
                {
                    args += ",";
                }
                args += additionalProfiles;
            }
        }
        descriptor.setAdditionalArguments( args );
        
        descriptor.setReleaseStrategyId( releaseStrategyId );

        return descriptor;
    }

    /**
     * Gets the comma separated list of additional profiles for the release build.
     *
     * @return additional profiles to enable during release
     */
    protected String getAdditionalProfiles()
    {
        return null;
    }

    /**
     * Sets the component used to perform release actions.
     *
     * @param releaseManager The release manager implementation to use, must not be <code>null</code>.
     */
    void setReleaseManager( ReleaseManager releaseManager )
    {
        this.releaseManager = releaseManager;
    }

    /**
     * Gets the effective settings for this build.
     *
     * @return The effective settings for this build, never <code>null</code>.
     */
    Settings getSettings()
    {
        return settings;
    }

    protected final File getBasedir()
    {
        return basedir;
    }

    /**
     * Sets the base directory of the build.
     *
     * @param basedir The build's base directory, must not be <code>null</code>.
     */
    public void setBasedir( File basedir )
    {
        this.basedir = basedir;
    }

    public void setPomFileName( String pomFileName )
    {
        this.pomFileName = pomFileName;
    }
    
    /**
     * Gets the list of projects in the build reactor.
     *
     * @return The list of reactor project, never <code>null</code>.
     */
    public List<MavenProject> getReactorProjects()
    {
        return reactorProjects;
    }

    /**
     * Add additional arguments.
     *
     * @param argument The argument to add, must not be <code>null</code>.
     */
    protected void addArgument( String argument )
    {
        if ( arguments != null )
        {
            arguments += " " + argument;
        }
        else
        {
            arguments = argument;
        }
    }
    
    static Path getCommonBasedir( List<MavenProject> reactorProjects )
    {
        Path basePath = reactorProjects
                        .get( 0 )
                        .getBasedir()
                        .toPath();
        
        for ( MavenProject reactorProject : reactorProjects )
        {
            Path matchPath = reactorProject.getBasedir().toPath();
            while ( !basePath.startsWith( matchPath ) )
            {
                matchPath = matchPath.getParent();
            }
            basePath = matchPath;
        }
        
        return basePath;
    }
}
