package org.apache.maven.continuum.release.phase;

/*
 * 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.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.DefaultArtifactRepository;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.continuum.release.ContinuumReleaseException;
import org.apache.maven.profiles.DefaultProfileManager;
import org.apache.maven.profiles.ProfileManager;
import org.apache.maven.project.DuplicateProjectException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.MissingProjectException;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectSorter;
import org.apache.maven.settings.MavenSettingsBuilder;
import org.apache.maven.settings.Settings;
import org.apache.maven.shared.release.ReleaseExecutionException;
import org.apache.maven.shared.release.ReleaseFailureException;
import org.apache.maven.shared.release.ReleaseResult;
import org.apache.maven.shared.release.config.ReleaseDescriptor;
import org.apache.maven.shared.release.env.ReleaseEnvironment;
import org.apache.maven.shared.release.phase.AbstractReleasePhase;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.dag.CycleDetectedException;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

/**
 * Generate the reactor projects
 *
 * @author Edwin Punzalan
 * @version $Id$
 */
public class GenerateReactorProjectsPhase
    extends AbstractReleasePhase
    implements Contextualizable
{
    private MavenProjectBuilder projectBuilder;

    private MavenSettingsBuilder settingsBuilder;

    private PlexusContainer container;

    private static final char SET_SYSTEM_PROPERTY = 'D';

    private static final char ACTIVATE_PROFILES = 'P';

    public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects )
        throws ReleaseExecutionException, ReleaseFailureException
    {
        ReleaseResult result = new ReleaseResult();

        try
        {
            reactorProjects.addAll( getReactorProjects( releaseDescriptor ) );
        }
        catch ( ContinuumReleaseException e )
        {
            throw new ReleaseExecutionException( "Unable to get reactor projects: " + e.getMessage(), e );
        }

        result.setResultCode( ReleaseResult.SUCCESS );

        return result;
    }

    public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, Settings settings, List reactorProjects )
        throws ReleaseExecutionException, ReleaseFailureException
    {
        return execute( releaseDescriptor, settings, reactorProjects );
    }


    public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
                                  List reactorProjects )
        throws ReleaseExecutionException, ReleaseFailureException
    {
        return execute( releaseDescriptor, releaseEnvironment.getSettings(), reactorProjects );
    }

    public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
                                   List reactorProjects )
        throws ReleaseExecutionException, ReleaseFailureException
    {
        return execute( releaseDescriptor, releaseEnvironment.getSettings(), reactorProjects );
    }

    private List getReactorProjects( ReleaseDescriptor descriptor )
        throws ContinuumReleaseException
    {
        List<MavenProject> reactorProjects = new ArrayList<MavenProject>();

        MavenProject project;
        try
        {
            String arguments = descriptor.getAdditionalArguments();
            ArtifactRepository repository = getLocalRepository( arguments );
            ProfileManager profileManager = getProfileManager( getSettings() );

            if ( arguments != null )
            {
                activateProfiles( arguments, profileManager );
            }

            project = projectBuilder.build( getProjectDescriptorFile( descriptor ), repository, profileManager );

            reactorProjects.add( project );

            addModules( reactorProjects, project, repository );
        }
        catch ( ParseException e )
        {
            throw new ContinuumReleaseException( "Unable to parse arguments.", e );
        }
        catch ( ProjectBuildingException e )
        {
            throw new ContinuumReleaseException( "Failed to build project.", e );
        }

        try
        {
            reactorProjects = new ProjectSorter( reactorProjects ).getSortedProjects();
        }
        catch ( CycleDetectedException e )
        {
            throw new ContinuumReleaseException( "Failed to sort projects.", e );
        }
        catch ( DuplicateProjectException e )
        {
            throw new ContinuumReleaseException( "Failed to sort projects.", e );
        }
        catch ( MissingProjectException e )
        {
            throw new ContinuumReleaseException( "Failed to sort projects.", e );
        }

        return reactorProjects;
    }

    private void addModules( List<MavenProject> reactorProjects, MavenProject project, ArtifactRepository repository )
        throws ContinuumReleaseException
    {
        for ( Object o : project.getModules() )
        {
            String moduleDir = StringUtils.replace( o.toString(), '\\', '/' );

            File pomFile = new File( project.getBasedir(), moduleDir + "/pom.xml" );

            try
            {
                MavenProject reactorProject = projectBuilder.build( pomFile, repository, getProfileManager(
                    getSettings() ) );

                reactorProjects.add( reactorProject );

                addModules( reactorProjects, reactorProject, repository );
            }
            catch ( ProjectBuildingException e )
            {
                throw new ContinuumReleaseException( "Failed to build project.", e );
            }
        }
    }

    private File getProjectDescriptorFile( ReleaseDescriptor descriptor )
    {
        String parentPath = descriptor.getWorkingDirectory();

        String pomFilename = descriptor.getPomFileName();
        if ( pomFilename == null )
        {
            pomFilename = "pom.xml";
        }

        return new File( parentPath, pomFilename );
    }

    private ArtifactRepository getLocalRepository( String arguments )
        throws ContinuumReleaseException
    {
        String localRepository = null;
        boolean found = false;

        if ( arguments != null )
        {
            String[] args = arguments.split( " " );

            for ( String arg : args )
            {
                if ( arg.contains( "-Dmaven.repo.local=" ) )
                {
                    localRepository = arg.substring( arg.indexOf( "=" ) + 1 );

                    if ( localRepository.endsWith( "\"" ) )
                    {
                        localRepository = localRepository.substring( 0, localRepository.indexOf( "\"" ) );
                        break;
                    }

                    found = true;
                    continue;
                }

                if ( found )
                {
                    localRepository += " " + arg;

                    if ( localRepository.endsWith( "\"" ) )
                    {
                        localRepository = localRepository.substring( 0, localRepository.indexOf( "\"" ) );
                        break;
                    }
                }
            }
        }

        if ( localRepository == null )
        {
            localRepository = getSettings().getLocalRepository();
        }

        return new DefaultArtifactRepository( "local-repository", "file://" + localRepository,
                                              new DefaultRepositoryLayout() );
    }

    private ProfileManager getProfileManager( Settings settings )
    {
        Properties props = new Properties();
        return new DefaultProfileManager( container, settings, props );
    }

    private Settings getSettings()
        throws ContinuumReleaseException
    {
        try
        {
            return settingsBuilder.buildSettings();
        }
        catch ( IOException e )
        {
            throw new ContinuumReleaseException( "Failed to get Maven Settings.", e );
        }
        catch ( XmlPullParserException e )
        {
            throw new ContinuumReleaseException( "Failed to get Maven Settings.", e );
        }
    }

    @SuppressWarnings( "static-access" )
    private void activateProfiles( String arguments, ProfileManager profileManager )
        throws ParseException
    {
        CommandLineParser parser = new GnuParser();

        Options options = new Options();

        options.addOption( OptionBuilder.withLongOpt( "activate-profiles" ).withDescription(
            "Comma-delimited list of profiles to activate" ).hasArg().create( ACTIVATE_PROFILES ) );

        options.addOption( OptionBuilder.withLongOpt( "define" ).hasArg().withDescription(
            "Define a system property" ).create( SET_SYSTEM_PROPERTY ) );

        String[] args = StringUtils.split( arguments );

        CommandLine commandLine = parser.parse( options, args );

        if ( commandLine.hasOption( ACTIVATE_PROFILES ) )
        {
            String[] profileOptionValues = commandLine.getOptionValues( ACTIVATE_PROFILES );

            if ( profileOptionValues != null )
            {
                for ( int i = 0; i < profileOptionValues.length; ++i )
                {
                    StringTokenizer profileTokens = new StringTokenizer( profileOptionValues[i], "," );

                    while ( profileTokens.hasMoreTokens() )
                    {
                        String profileAction = profileTokens.nextToken().trim();

                        if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
                        {
                            profileManager.explicitlyDeactivate( profileAction.substring( 1 ) );
                        }
                        else if ( profileAction.startsWith( "+" ) )
                        {
                            profileManager.explicitlyActivate( profileAction.substring( 1 ) );
                        }
                        else
                        {
                            profileManager.explicitlyActivate( profileAction );
                        }
                    }
                }
            }
        }
    }

    public void contextualize( Context context )
        throws ContextException
    {
        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
    }


}
