package org.apache.maven.plugin;

/*
 * 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.execution.MavenSession;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.path.PathTranslator;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Evaluator for plugin parameters expressions. Content surrounded by <code>${</code> and <code>}</code> is evaluated.
 * Recognized values are:<ul>
 * <li><code>localRepository</code></li>
 * <li><code>session</code></li>
 * <li><code>reactorProjects</code></li>
 * <li><code>reports</code></li>
 * <li><code>mojoExecution</code></li>
 * <li><code>project</code></li>
 * <li><code>executedProject</code></li>
 * <li><code>project.*</code></li>
 * <li><code>plugin.*</code></li>
 * <li><code>settings</code></li>
 * <li><code>settings.*</code></li>
 * <li><code>basedir</code></li>
 * <li>system properties</li>
 * <li>project properties</li>
 * </ul>
 * 
 * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
 * @version $Id$
 * @todo belong in MavenSession, so it only gets created once?
 */
public class PluginParameterExpressionEvaluator
    implements ExpressionEvaluator
{
    private static final Map BANNED_EXPRESSIONS;

    private static final Map DEPRECATED_EXPRESSIONS;

    static
    {
        Map deprecated = new HashMap();

        deprecated.put( "project.build.resources", "project.resources" );
        deprecated.put( "project.build.testResources", "project.testResources" );

        DEPRECATED_EXPRESSIONS = deprecated;

        Map banned = new HashMap();

        BANNED_EXPRESSIONS = banned;
    }

    private final PathTranslator pathTranslator;

    private final MavenSession context;

    private final Logger logger;

    private final MojoExecution mojoExecution;

    private final MavenProject project;

    private final String basedir;

    private final Properties properties;

    public PluginParameterExpressionEvaluator( MavenSession context,
                                               MojoExecution mojoExecution,
                                               PathTranslator pathTranslator,
                                               Logger logger,
                                               MavenProject project,
                                               Properties properties )
    {
        this.context = context;
        this.mojoExecution = mojoExecution;
        this.pathTranslator = pathTranslator;
        this.logger = logger;
        this.project = project;
        this.properties = properties;

        String basedir = null;

        if ( project != null )
        {
            File baseDir = project.getBasedir();

            // this should always be the case for non-super POM instances...
            if ( baseDir != null )
            {
                basedir = baseDir.getAbsolutePath();
            }
        }

        if ( basedir == null )
        {
            basedir = System.getProperty( "user.dir" );
        }

        this.basedir = basedir;
    }

    public Object evaluate( String expr )
        throws ExpressionEvaluationException
    {
        Object value = null;

        if ( expr == null )
        {
            return null;
        }

        String expression = stripTokens( expr );
        if ( expression.equals( expr ) )
        {
            int index = expr.indexOf( "${" );
            if ( index >= 0 )
            {
                int lastIndex = expr.indexOf( "}", index );
                if ( lastIndex >= 0 )
                {
                    String retVal = expr.substring( 0, index );

                    if ( index > 0 && expr.charAt( index - 1 ) == '$' )
                    {
                        retVal += expr.substring( index + 1, lastIndex + 1 );
                    }
                    else
                    {
                        retVal += evaluate( expr.substring( index, lastIndex + 1 ) );
                    }

                    retVal += evaluate( expr.substring( lastIndex + 1 ) );
                    return retVal;
                }
            }

            // Was not an expression
            if ( expression.indexOf( "$$" ) > -1 )
            {
                return expression.replaceAll( "\\$\\$", "\\$" );
            }
            else
            {
                return expression;
            }
        }

        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
        if ( BANNED_EXPRESSIONS.containsKey( expression ) )
        {
            throw new ExpressionEvaluationException( "The parameter expression: \'" + expression
                + "\' used in mojo: \'" + mojoDescriptor.getGoal() + "\' is banned. Use \'"
                + BANNED_EXPRESSIONS.get( expression ) + "\' instead." );
        }
        else if ( DEPRECATED_EXPRESSIONS.containsKey( expression ) )
        {
            logger.warn( "The parameter expression: \'" + expression + "\' used in mojo: \'"
                + mojoDescriptor.getGoal() + "\' has been deprecated. Use \'" + DEPRECATED_EXPRESSIONS.get( expression )
                + "\' instead." );
        }

        if ( "localRepository".equals( expression ) )
        {
            value = context.getLocalRepository();
        }
        else if ( "session".equals( expression ) )
        {
            value = context;
        }
        else if ( "reactorProjects".equals( expression ) )
        {
            value = context.getSortedProjects();
        }
        else if ( "reports".equals( expression ) )
        {
            value = mojoExecution.getReports();
        }
        else if ( "mojoExecution".equals( expression ) )
        {
        	value = mojoExecution;
        }
        else if ( "project".equals( expression ) )
        {
            value = project;
        }
        else if ( "executedProject".equals( expression ) )
        {
            value = project.getExecutionProject();
        }
        else if ( expression.startsWith( "project" ) )
        {
            try
            {
                int pathSeparator = expression.indexOf( "/" );

                if ( pathSeparator > 0 )
                {
                    String pathExpression = expression.substring( 0, pathSeparator );
                    value = ReflectionValueExtractor.evaluate( pathExpression, project );
                    value = value + expression.substring( pathSeparator );
                }
                else
                {
                    value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), project );
                }
            }
            catch ( Exception e )
            {
                // TODO: don't catch exception
                throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
                                                         e );
            }
        }
        else if ( expression.startsWith( "plugin" ) )
        {
            try
            {
                int pathSeparator = expression.indexOf( "/" );

                PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();

                if ( pathSeparator > 0 )
                {
                    String pathExpression = expression.substring( 1, pathSeparator );
                    value = ReflectionValueExtractor.evaluate( pathExpression, pluginDescriptor );
                    value = value + expression.substring( pathSeparator );
                }
                else
                {
                    value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), pluginDescriptor );
                }
            }
            catch ( Exception e )
            {
                // TODO: don't catch exception
                throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
                                                         e );
            }
        }
        else if ( "settings".equals( expression ) )
        {
            value = context.getSettings();
        }
        else if ( expression.startsWith( "settings" ) )
        {
            try
            {
                int pathSeparator = expression.indexOf( "/" );

                if ( pathSeparator > 0 )
                {
                    String pathExpression = expression.substring( 1, pathSeparator );
                    value = ReflectionValueExtractor.evaluate( pathExpression, context.getSettings() );
                    value = value + expression.substring( pathSeparator );
                }
                else
                {
                    value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), context.getSettings() );
                }
            }
            catch ( Exception e )
            {
                // TODO: don't catch exception
                throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
                                                         e );
            }
        }
        else if ( "basedir".equals( expression ) )
        {
            value = basedir;
        }
        else if ( expression.startsWith( "basedir" ) )
        {
            int pathSeparator = expression.indexOf( "/" );

            if ( pathSeparator > 0 )
            {
                value = basedir + expression.substring( pathSeparator );
            }
            else
            {
                logger.error( "Got expression '" + expression + "' that was not recognised" );
            }
        }

        if ( value == null )
        {
            // The CLI should win for defining properties

            if ( value == null && properties != null )
            {
                // We will attempt to get nab a system property as a way to specify a
                // parameter to a plugins. My particular case here is allowing the surefire
                // plugin to run a single test so I want to specify that class on the cli
                // as a parameter.

                value = properties.getProperty( expression );
            }

            if ( value == null && project != null && project.getProperties() != null )
            {
                value = project.getProperties().getProperty( expression );
            }

        }

        if ( value instanceof String )
        {
            // TODO: without #, this could just be an evaluate call...

            String val = (String) value;

            int exprStartDelimiter = val.indexOf( "${" );

            if ( exprStartDelimiter >= 0 )
            {
                if ( exprStartDelimiter > 0 )
                {
                    value = val.substring( 0, exprStartDelimiter ) + evaluate( val.substring( exprStartDelimiter ) );
                }
                else
                {
                    value = evaluate( val.substring( exprStartDelimiter ) );
                }
            }
        }

        return value;
    }

    private String stripTokens( String expr )
    {
        if ( expr.startsWith( "${" ) && expr.indexOf( "}" ) == expr.length() - 1 )
        {
            expr = expr.substring( 2, expr.length() - 1 );
        }
        return expr;
    }

    public File alignToBaseDirectory( File file )
    {
        File basedir;

        if ( project != null && project.getFile() != null )
        {
            basedir = project.getFile().getParentFile();
        }
        else
        {
            basedir = new File( "." ).getAbsoluteFile().getParentFile();
        }

        return new File( pathTranslator.alignToBaseDirectory( file.getPath(), basedir ) );
    }

}
