package org.apache.maven.plugin.assembly.utils;

/*
 * 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.execution.MavenSession;
import org.apache.maven.plugin.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugin.assembly.format.AssemblyFormattingException;
import org.apache.maven.plugin.assembly.model.Assembly;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
import org.codehaus.plexus.interpolation.PrefixedPropertiesValueSource;
import org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
import org.codehaus.plexus.interpolation.StringSearchInterpolator;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.cli.CommandLineUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;

/**
 * @version $Id$
 */
public final class AssemblyFormatUtils
{

    private AssemblyFormatUtils()
    {
    }

    /**
     * Get the full name of the distribution artifact
     * 
     * @param assembly
     * @return the distribution name
     */
    public static String getDistributionName( final Assembly assembly, final AssemblerConfigurationSource configSource )
    {
        final String finalName = configSource.getFinalName();
        final boolean appendAssemblyId = configSource.isAssemblyIdAppended();
        final String classifier = configSource.getClassifier();

        String distributionName = finalName;
        if ( appendAssemblyId )
        {
            if ( !StringUtils.isEmpty( assembly.getId() ) )
            {
                distributionName = finalName + "-" + assembly.getId();
            }
        }
        else if ( classifier != null )
        {
            distributionName = finalName + "-" + classifier;
        }

        return distributionName;
    }

    public static String getOutputDirectory( final String output, final MavenProject mainProject,
                                             final MavenProject artifactProject, final String finalName,
                                             final AssemblerConfigurationSource configSource )
        throws AssemblyFormattingException
    {
        return getOutputDirectory( output, mainProject, null, artifactProject, finalName, configSource );
    }

    /**
     * ORDER OF INTERPOLATION PRECEDENCE:
     * <ol>
     * <li>Support for special expressions, like ${finalName} (use the assembly plugin configuration not the build
     * config)</li>
     * <li>prefixed with "module." if moduleProject is non-null
     * <ol>
     * <li>MavenProject instance for module being assembled</li>
     * </ol>
     * </li>
     * <li>prefixed with "artifact." if artifactProject is non-null
     * <ol>
     * <li>MavenProject instance for artifact</li>
     * </ol>
     * </li>
     * <li>user-defined properties from the command line</li>
     * <li>prefixed with "pom." or "project.", or no prefix at all
     * <ol>
     * <li>MavenProject instance from current build</li>
     * </ol>
     * </li>
     * <li>properties from main project</li>
     * <li>system properties, from the MavenSession instance (to support IDEs)</li>
     * <li>environment variables.</li>
     * </ol>
     */
    public static String getOutputDirectory( final String output, final MavenProject mainProject,
                                             final MavenProject moduleProject, final MavenProject artifactProject,
                                             final String finalName, final AssemblerConfigurationSource configSource )
        throws AssemblyFormattingException
    {
        String value = output;
        if ( value == null )
        {
            value = "";
        }

        final StringSearchInterpolator interpolator = new StringSearchInterpolator();

        final Properties specialExpressionOverrides = new Properties();

        if ( finalName != null )
        {
            specialExpressionOverrides.setProperty( "finalName", finalName );
            specialExpressionOverrides.setProperty( "build.finalName", finalName );
        }

        // 1
        interpolator.addValueSource( new PropertiesBasedValueSource( specialExpressionOverrides ) );

        if ( moduleProject != null )
        {
            // 2
            interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleProject ) );
            interpolator.addValueSource( new PrefixedPropertiesValueSource( "module.properties.",
                                                                            moduleProject.getProperties() ) );
            if ( moduleProject.getArtifact() != null )
            {
                interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleProject.getArtifact() ) );
            }
        }

        if ( artifactProject != null )
        {
            // 3
            interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifactProject ) );
            interpolator.addValueSource( new PrefixedPropertiesValueSource( "artifact.properties.",
                                                                            artifactProject.getProperties() ) );
            if ( artifactProject.getArtifact() != null )
            {
                interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifactProject.getArtifact() ) );
            }
        }

        MavenSession session = null;

        if ( configSource != null )
        {
            session = configSource.getMavenSession();

            if ( session != null )
            {
                Properties userProperties = null;
                try
                {
                    userProperties = session.getExecutionProperties();
                }
                catch ( final NoSuchMethodError nsmer )
                {
                    // OK, so user is using Maven <= 2.0.8. No big deal.
                }

                if ( userProperties != null )
                {
                    // 4
                    interpolator.addValueSource( new PropertiesBasedValueSource( userProperties ) );
                }
            }
        }

        if ( mainProject != null )
        {
            // 5
            interpolator.addValueSource( new PrefixedObjectValueSource( InterpolationConstants.PROJECT_PREFIXES,
                                                                        mainProject, true ) );

            // 6
            interpolator.addValueSource( new PrefixedPropertiesValueSource(
                                                                            InterpolationConstants.PROJECT_PROPERTIES_PREFIXES,
                                                                            mainProject.getProperties(), true ) );
        }

        Properties commandLineProperties = System.getProperties();
        if ( session != null )
        {
            commandLineProperties = new Properties();
            if ( session.getExecutionProperties() != null )
            {
                commandLineProperties.putAll( session.getExecutionProperties() );
            }

            if ( session.getUserProperties() != null )
            {
                commandLineProperties.putAll( session.getUserProperties() );
            }
        }

        // 7
        interpolator.addValueSource( new PropertiesBasedValueSource( commandLineProperties ) );

        try
        {
            // 8
            interpolator.addValueSource( new PrefixedPropertiesValueSource( Collections.singletonList( "env." ),
                                                                            CommandLineUtils.getSystemEnvVars( false ),
                                                                            true ) );
        }
        catch ( final IOException e )
        {
            throw new AssemblyFormattingException( "Failed to retrieve OS environment variables. Reason: "
                + e.getMessage(), e );
        }

        try
        {
            value = interpolator.interpolate( value );
        }
        catch ( final InterpolationException e )
        {
            throw new AssemblyFormattingException( "Failed to interpolate output directory. Reason: " + e.getMessage(),
                                                   e );
        }

        if ( ( value.length() > 0 ) && !value.endsWith( "/" ) && !value.endsWith( "\\" ) )
        {
            value += "/";
        }

        if ( ( value.length() > 0 ) && ( value.startsWith( "/" ) || value.startsWith( "\\" ) ) )
        {
            value = value.substring( 1 );
        }

        value = StringUtils.replace( value, "//", "/" );
        value = StringUtils.replace( value, "\\\\", "\\" );
        value = fixRelativeRefs( value );

        return value;
    }

    public static String evaluateFileNameMapping( final String expression, final Artifact artifact,
                                                  final MavenProject mainProject, final MavenProject artifactProject,
                                                  final AssemblerConfigurationSource configSource )
        throws AssemblyFormattingException
    {
        return evaluateFileNameMapping( expression, artifact, mainProject, null, null, artifactProject, configSource );
    }

    /**
     * ORDER OF INTERPOLATION PRECEDENCE:
     * <ol>
     * <li>prefixed with "module.", if moduleProject != null
     * <ol>
     * <li>Artifact instance for module, if moduleArtifact != null</li>
     * <li>ArtifactHandler instance for module, if moduleArtifact != null</li>
     * <li>MavenProject instance for module</li>
     * </ol>
     * </li>
     * <li>prefixed with "artifact."
     * <ol>
     * <li>Artifact instance</li>
     * <li>ArtifactHandler instance for artifact</li>
     * <li>MavenProject instance for artifact</li>
     * </ol>
     * </li>
     * <li>prefixed with "pom." or "project."
     * <ol>
     * <li>MavenProject instance from current build</li>
     * </ol>
     * </li>
     * <li>no prefix, using main project instance
     * <ol>
     * <li>MavenProject instance from current build</li>
     * </ol>
     * </li>
     * <li>Support for special expressions, like ${dashClassifier?}</li>
     * <li>user-defined properties from the command line</li>
     * <li>properties from main project</li>
     * <li>system properties, from the MavenSession instance (to support IDEs)</li>
     * <li>environment variables.</li>
     * </ol>
     */
    public static String evaluateFileNameMapping( final String expression, final Artifact artifact,
                                                  final MavenProject mainProject, final MavenProject moduleProject,
                                                  final Artifact moduleArtifact, final MavenProject artifactProject,
                                                  final AssemblerConfigurationSource configSource )
        throws AssemblyFormattingException
    {
        String value = expression;

        // TODO: This is BAD! Accessors SHOULD NOT change the behavior of the object.
        // [jdcasey; 16-Aug-1007] This is fixed in SVN, just waiting for it to pass out of legacy.
        artifact.isSnapshot();

        final StringSearchInterpolator interpolator = new StringSearchInterpolator();

        if ( moduleArtifact != null )
        {
            // 1A
            interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleArtifact ) );

            // 1B
            interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleArtifact.getArtifactHandler() ) );
            interpolator.addValueSource( new PrefixedObjectValueSource( "module.handler.",
                                                                        moduleArtifact.getArtifactHandler() ) );
        }

        // 1C
        if ( moduleProject != null )
        {
            interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleProject ) );
            interpolator.addValueSource( new PrefixedPropertiesValueSource( "module.properties.",
                                                                            moduleProject.getProperties() ) );
            if ( moduleProject.getArtifact() != null )
            {
                interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleProject.getArtifact() ) );
            }
        }

        // 2A
        interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifact ) );

        // 2B
        interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifact.getArtifactHandler() ) );
        interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.handler.", artifact.getArtifactHandler() ) );

        // 2C
        if ( artifactProject != null )
        {
            interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifactProject ) );
            interpolator.addValueSource( new PrefixedPropertiesValueSource( "artifact.properties.",
                                                                            artifactProject.getProperties() ) );
            if ( artifactProject.getArtifact() != null )
            {
                interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifactProject.getArtifact() ) );
            }
        }

        if ( mainProject != null )
        {
            // 3
            // 4
            interpolator.addValueSource( new PrefixedObjectValueSource( InterpolationConstants.PROJECT_PREFIXES,
                                                                        mainProject, true ) );
        }

        final Properties specialRules = new Properties();

        final String classifier = ProjectUtils.getClassifier( artifact );
        if ( classifier != null )
        {
            specialRules.setProperty( "dashClassifier?", "-" + classifier );
            specialRules.setProperty( "dashClassifier", "-" + classifier );
        }
        else
        {
            specialRules.setProperty( "dashClassifier?", "" );
            specialRules.setProperty( "dashClassifier", "" );
        }

        // 5
        interpolator.addValueSource( new PropertiesBasedValueSource( specialRules ) );

        MavenSession session = null;
        if ( configSource != null )
        {
            session = configSource.getMavenSession();

            if ( session != null )
            {
                Properties userProperties = null;
                try
                {
                    userProperties = session.getExecutionProperties();
                }
                catch ( final NoSuchMethodError nsmer )
                {
                    // OK, so user is using Maven <= 2.0.8. No big deal.
                }

                if ( userProperties != null )
                {
                    // 6
                    interpolator.addValueSource( new PropertiesBasedValueSource( userProperties ) );
                }
            }
        }

        if ( mainProject != null )
        {
            // 7
            interpolator.addValueSource( new PrefixedPropertiesValueSource(
                                                                            InterpolationConstants.PROJECT_PROPERTIES_PREFIXES,
                                                                            mainProject.getProperties(), true ) );
        }

        Properties commandLineProperties = System.getProperties();
        if ( session != null )
        {
            commandLineProperties = new Properties();
            if ( session.getExecutionProperties() != null )
            {
                commandLineProperties.putAll( session.getExecutionProperties() );
            }

            if ( session.getUserProperties() != null )
            {
                commandLineProperties.putAll( session.getUserProperties() );
            }
        }

        // 8
        interpolator.addValueSource( new PropertiesBasedValueSource( commandLineProperties ) );

        try
        {
            // 9
            interpolator.addValueSource( new PrefixedPropertiesValueSource( Collections.singletonList( "env." ),
                                                                            CommandLineUtils.getSystemEnvVars( false ),
                                                                            true ) );
        }
        catch ( final IOException e )
        {
            throw new AssemblyFormattingException( "Failed to retrieve OS environment variables. Reason: "
                + e.getMessage(), e );
        }

        try
        {
            value = interpolator.interpolate( value );
        }
        catch ( final InterpolationException e )
        {
            throw new AssemblyFormattingException( "Failed to interpolate output filename mapping. Reason: "
                + e.getMessage(), e );
        }

        value = StringUtils.replace( value, "//", "/" );
        value = StringUtils.replace( value, "\\\\", "\\" );
        value = fixRelativeRefs( value );

        return value;
    }

    public static String fixRelativeRefs( String src )
    {
        String value = src;

        String[] separators = { "/", "\\" };

        String finalSep = null;
        for ( String sep : separators )
        {
            if ( value.endsWith( sep ) )
            {
                finalSep = sep;
            }

            if ( value.contains( "." + sep ) )
            {
                List<String> parts = new ArrayList<String>();
                parts.addAll( Arrays.asList( value.split( sep.replace( "\\", "\\\\" ) ) ) );

                for ( ListIterator<String> it = parts.listIterator(); it.hasNext(); )
                {
                    String part = it.next();
                    if ( ".".equals( part ) )
                    {
                        it.remove();
                    }
                    else if ( "..".equals( part ) )
                    {
                        it.remove();
                        if ( it.hasPrevious() )
                        {
                            it.previous();
                            it.remove();
                        }
                    }
                }

                value = StringUtils.join( parts.iterator(), sep );
            }
        }

        if ( finalSep != null && value.length() > 0 && !value.endsWith( finalSep ) )
        {
            value += finalSep;
        }

        return value;
    }
}
