package org.apache.maven.plugins.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.plugins.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
import org.apache.maven.plugins.assembly.model.Assembly;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.utils.Os;
import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
import org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource;
import org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource;
import org.codehaus.plexus.interpolation.fixed.PropertiesBasedValueSource;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.StringUtils;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;

/**
 *
 */
public final class AssemblyFormatUtils
{

    private AssemblyFormatUtils()
    {
    }

    /**
     * Get the full name of the distribution artifact
     *
     * @param assembly the 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();

        String distributionName = finalName;
        if ( appendAssemblyId )
        {
            distributionName = finalName + "-" + assembly.getId();
        }

        return distributionName;
    }


    @Nonnull
    public static FixedStringSearchInterpolator finalNameInterpolator( String finalName )
    {
        final Properties specialExpressionOverrides = new Properties();

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

        return FixedStringSearchInterpolator.create( new PropertiesBasedValueSource( specialExpressionOverrides ) );
    }

    @Nonnull
    public static FixedStringSearchInterpolator moduleProjectInterpolator( final MavenProject moduleProject )
    {
        if ( moduleProject != null )
        {
            return FixedStringSearchInterpolator.createWithPermittedNulls(
                new PrefixedObjectValueSource( "module.", moduleProject ),
                new PrefixedPropertiesValueSource( "module.properties.", moduleProject.getProperties() ),
                moduleProject.getArtifact() != null
                    ? new PrefixedObjectValueSource( "module.", moduleProject.getArtifact() )
                    : null );
        }
        else
        {
            return FixedStringSearchInterpolator.empty();
        }

    }

    public static FixedStringSearchInterpolator moduleArtifactInterpolator( Artifact moduleArtifact )
    {
        if ( moduleArtifact != null )
        {
            // CHECKSTYLE_OFF: LineLength
            return FixedStringSearchInterpolator.create( new PrefixedObjectValueSource( "module.", moduleArtifact ),
                                                         new PrefixedObjectValueSource( "module.",
                                                                                        moduleArtifact
                                                                                            .getArtifactHandler() ),
                                                         new PrefixedObjectValueSource( "module.handler.",
                                                                                        moduleArtifact
                                                                                            .getArtifactHandler() ) );
            // CHECKSTYLE_ON: LineLength
        }
        else
        {
            return FixedStringSearchInterpolator.empty();
        }

    }

    @Nonnull
    public static FixedStringSearchInterpolator artifactProjectInterpolator( final MavenProject artifactProject )
    {
        if ( artifactProject != null )
        {
            PrefixedObjectValueSource vs = null;
            if ( artifactProject.getArtifact() != null )
            {
                vs = new PrefixedObjectValueSource( "artifact.", artifactProject.getArtifact() );
            }

            return FixedStringSearchInterpolator.createWithPermittedNulls(
                new PrefixedObjectValueSource( "artifact.", artifactProject ),
                new PrefixedPropertiesValueSource( "artifact.properties.", artifactProject.getProperties() ), vs );


        }
        else
        {
            return FixedStringSearchInterpolator.empty();
        }


    }

    @Nonnull
    public static FixedStringSearchInterpolator artifactInterpolator( @Nonnull final Artifact artifact )
    {
        return FixedStringSearchInterpolator.create( new PrefixedObjectValueSource( "artifact.", artifact ),
                                                     new PrefixedObjectValueSource( "artifact.",
                                                                                    artifact.getArtifactHandler() ),
                                                     new PrefixedObjectValueSource( "artifact.handler.",
                                                                                    artifact.getArtifactHandler() ) );
    }


    @Nonnull
    public static FixedStringSearchInterpolator classifierRules( final Artifact artifact )
    {
        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", "" );
        }

        return FixedStringSearchInterpolator.create( new PropertiesBasedValueSource( specialRules ) );
    }


    /**
     * 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 artifactProject,
                                             final String finalName, final AssemblerConfigurationSource configSource )
        throws AssemblyFormattingException
    {
        return getOutputDirectory( output, finalName, configSource, moduleProjectInterpolator( null ),
                                   artifactProjectInterpolator( artifactProject ) );
    }


    private static FixedStringSearchInterpolator executionPropertiesInterpolator(
        AssemblerConfigurationSource configSource )
    {
        MavenSession session;

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

            if ( session != null )
            {
                Properties userProperties = session.getExecutionProperties(); // this is added twice....

                if ( userProperties != null )
                {
                    return FixedStringSearchInterpolator.create( new PropertiesBasedValueSource( userProperties ) );
                }
            }
        }
        return FixedStringSearchInterpolator.empty();
    }

    private static FixedStringSearchInterpolator mainProjectOnlyInterpolator( MavenProject mainProject )
    {
        if ( mainProject != null )
        {
            // 5
            return FixedStringSearchInterpolator.create(
                new org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource(
                    InterpolationConstants.PROJECT_PREFIXES, mainProject, true ) );
        }
        else
        {
            return FixedStringSearchInterpolator.empty();
        }
    }


    /**
     * 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>
     */


    @Nonnull
    public static String fixRelativeRefs( @Nonnull 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<>();
                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;
    }


    /**
     * 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, @Nonnull final Artifact artifact,
                                                  @Nullable final MavenProject mainProject,
                                                  @Nullable final Artifact moduleArtifact,
                                                  @Nonnull final AssemblerConfigurationSource configSource,
                                                  FixedStringSearchInterpolator moduleProjectInterpolator,
                                                  FixedStringSearchInterpolator artifactProjectInterpolator )
        throws AssemblyFormattingException
    {
        String value = expression;

        final FixedStringSearchInterpolator interpolator =
            FixedStringSearchInterpolator.create( moduleArtifactInterpolator( moduleArtifact ),
                                                  moduleProjectInterpolator, artifactInterpolator( artifact ),
                                                  artifactProjectInterpolator,
                                                  mainProjectOnlyInterpolator( mainProject ),
                                                  classifierRules( artifact ),
                                                  executionPropertiesInterpolator( configSource ),
                                                  configSource.getMainProjectInterpolator(),
                                                  configSource.getCommandLinePropsInterpolator(),
                                                  configSource.getEnvInterpolator() );

        value = interpolator.interpolate( value );

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

        return value;
    }

    /**
     * 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 String finalName,
                                             final AssemblerConfigurationSource configSource,
                                             FixedStringSearchInterpolator moduleProjectIntrpolator,
                                             FixedStringSearchInterpolator artifactProjectInterpolator )
        throws AssemblyFormattingException
    {
        String value = output;
        if ( value == null )
        {
            value = "";
        }

        final FixedStringSearchInterpolator interpolator =
            FixedStringSearchInterpolator.create( finalNameInterpolator( finalName ), moduleProjectIntrpolator,
                                                  artifactProjectInterpolator,
                                                  executionPropertiesInterpolator( configSource ),
                                                  configSource.getMainProjectInterpolator(),
                                                  configSource.getCommandLinePropsInterpolator(),
                                                  configSource.getEnvInterpolator() );

        value = interpolator.interpolate( value );

        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 void warnForPlatformSpecifics( Logger logger, String destDirectory )
    {
        if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
        {
            if ( isUnixRootReference( destDirectory ) )
            {
                logger.error( "OS=Windows and the assembly descriptor contains a *nix-specific root-relative reference"
                                  + " (starting with slash): " + destDirectory );
            }
            else if ( isWindowsPath( destDirectory ) )
            {
                logger.warn( "The assembly descriptor contains a Windows-specific directory reference"
                                 + " (with a drive letter). This is not portable and will fail on non-Windows: "
                                 + destDirectory );
            }
        }
        else
        {
            if ( isWindowsPath( destDirectory ) )
            {
                logger.error(
                    "OS=Non-Windows and the assembly descriptor contains a Windows-specific directory reference"
                        + " (with a drive letter): " + destDirectory );
            }
            else if ( isUnixRootReference( destDirectory ) )
            {
                logger.warn( "The assembly descriptor contains a *nix-specific root-relative reference"
                                 + " (starting with slash). This is not portable and might fail on Windows: "
                                 + destDirectory );
            }
        }
    }

    static boolean isWindowsPath( String destDirectory )
    {
        return ( destDirectory != null && destDirectory.length() >= 2 && destDirectory.charAt( 1 ) == ':' );
    }

    static boolean isUnixRootReference( String destDirectory )
    {
        return ( destDirectory != null && destDirectory.startsWith( "/" ) );
    }


}
