package org.apache.maven.plugin.descriptor;

/*
 * 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.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.maven.plugin.Mojo;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;

/**
 * The bean containing the Mojo descriptor.<br>
 * For more information about the usage tag, have a look to:
 * <a href="https://maven.apache.org/developers/mojo-api-specification.html">
 * https://maven.apache.org/developers/mojo-api-specification.html</a>
 *
 * TODO is there a need for the delegation of MavenMojoDescriptor to this?
 * Why not just extend ComponentDescriptor here?
 */
public class MojoDescriptor
    extends ComponentDescriptor<Mojo>
    implements Cloneable
{
    /** The Plexus component type */
    public static final String MAVEN_PLUGIN = "maven-plugin";

    /** "once-per-session" execution strategy */
    public static final String SINGLE_PASS_EXEC_STRATEGY = "once-per-session";

    /** "always" execution strategy */
    public static final String MULTI_PASS_EXEC_STRATEGY = "always";

    private static final String DEFAULT_INSTANTIATION_STRATEGY = "per-lookup";

    private static final String DEFAULT_LANGUAGE = "java";

    private final ArrayList<Parameter> parameters;

    /** By default, the execution strategy is "once-per-session" */
    private String executionStrategy = SINGLE_PASS_EXEC_STRATEGY;

    /**
     * The goal name for the Mojo, that users will reference from the command line to execute the Mojo directly, or
     * inside a POM in order to provide Mojo-specific configuration.
     */
    private String goal;

    /**
     * Defines a default phase to bind a mojo execution to if the user does not explicitly set a phase in the POM.
     * <i>Note:</i> This will not automagically make a mojo run when the plugin declaration is added to the POM. It
     * merely enables the user to omit the <code>&lt;phase&gt;</code> element from the surrounding
     * <code>&lt;execution&gt;</code> element.
     */
    private String phase;

    /** Specify the version when the Mojo was added to the API. Similar to Javadoc since. */
    private String since;

    /** Reference the invocation phase of the Mojo. */
    private String executePhase;

    /** Reference the invocation goal of the Mojo. */
    private String executeGoal;

    /** Reference the invocation lifecycle of the Mojo. */
    private String executeLifecycle;

    /**
     * Description with reason of Mojo deprecation. Similar to Javadoc {@code @deprecated}.
     * This will trigger a warning when a user tries to use a Mojo marked as deprecated.
     */
    private String deprecated;

    /**
     * Flags this Mojo to run it in a multi-module way, i.e. aggregate the build with the set of projects listed as
     * modules. By default, no need to aggregate the Maven project and its child modules
     */
    private boolean aggregator = false;

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    /** Specify the required dependencies in a specified scope */
    private String dependencyResolutionRequired = null;

    /**
     * The scope of (transitive) dependencies that should be collected but not resolved.
     * @since 3.0-alpha-3
     */
    private String dependencyCollectionRequired;

    /**  By default, the Mojo needs a Maven project to be executed */
    private boolean projectRequired = true;

    /**  By default, the Mojo is assumed to work offline as well */
    private boolean onlineRequired = false;

    /**  Plugin configuration */
    private PlexusConfiguration mojoConfiguration;

    /**  Plugin descriptor */
    private PluginDescriptor pluginDescriptor;

    /**  By default, the Mojo is inherited */
    private boolean inheritedByDefault = true;

    /**  By default, the Mojo cannot be invoked directly */
    private boolean directInvocationOnly = false;

    /**  By default, the Mojo don't need reports to run */
    private boolean requiresReports = false;

    /**
     * By default, mojos are not threadsafe
     * @since 3.0-beta-2
     */
    private boolean threadSafe = false;

    /**
     * Default constructor.
     */
    public MojoDescriptor()
    {
        this.parameters = new ArrayList<>();
        setInstantiationStrategy( DEFAULT_INSTANTIATION_STRATEGY );
        setComponentFactory( DEFAULT_LANGUAGE );
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    /**
     * @return the language of this Mojo, i.e. <code>java</code>
     */
    public String getLanguage()
    {
        return getComponentFactory();
    }

    /**
     * @param language the new language
     */
    public void setLanguage( String language )
    {
        setComponentFactory( language );
    }

    /**
     * @return Description with reason of a Mojo deprecation.
     */
    public String getDeprecated()
    {
        return deprecated;
    }

    /**
     * @param deprecated Description with reason of a Mojo deprecation.
     */
    public void setDeprecated( String deprecated )
    {
        this.deprecated = deprecated;
    }

    /**
     * @return the list of parameters copy. Any change to returned list is NOT reflected on this instance. To add
     * parameters, use {@link #addParameter(Parameter)} method.
     */
    public List<Parameter> getParameters()
    {
        return new ArrayList<>( parameters  );
    }

    /**
     * @param parameters the new list of parameters
     * @throws DuplicateParameterException if any
     */
    public void setParameters( List<Parameter> parameters )
        throws DuplicateParameterException
    {
        this.parameters.clear();
        for ( Parameter parameter : parameters )
        {
            addParameter( parameter );
        }
    }

    /**
     * @param parameter add a new parameter
     * @throws DuplicateParameterException if any
     */
    public void addParameter( Parameter parameter )
        throws DuplicateParameterException
    {
        if ( parameters.contains( parameter ) )
        {
            throw new DuplicateParameterException( parameter.getName()
                + " has been declared multiple times in mojo with goal: " + getGoal() + " (implementation: "
                + getImplementation() + ")" );
        }

        parameters.add( parameter );
    }

    /**
     * @return the list parameters as a Map (keyed by {@link Parameter#getName()}) that is built from
     * {@link #parameters} list on each call. In other words, the map returned is built on fly and is a copy.
     * Any change to this map is NOT reflected on list and other way around!
     */
    public Map<String, Parameter> getParameterMap()
    {
        LinkedHashMap<String, Parameter> parameterMap = new LinkedHashMap<>();

        for ( Parameter pd : parameters )
        {
            parameterMap.put( pd.getName(), pd );
        }

        return parameterMap;
    }

    // ----------------------------------------------------------------------
    // Dependency requirement
    // ----------------------------------------------------------------------

    /**
     * @param requiresDependencyResolution the new required dependencies in a specified scope
     */
    public void setDependencyResolutionRequired( String requiresDependencyResolution )
    {
        this.dependencyResolutionRequired = requiresDependencyResolution;
    }

    public String getDependencyResolutionRequired()
    {
        return dependencyResolutionRequired;
    }

    /**
     * @return the required dependencies in a specified scope
     * TODO the name is not intelligible
     */
    @Deprecated
    public String isDependencyResolutionRequired()
    {
        return dependencyResolutionRequired;
    }

    /**
     * @since 3.0-alpha-3
     */
    public void setDependencyCollectionRequired( String requiresDependencyCollection )
    {
        this.dependencyCollectionRequired = requiresDependencyCollection;
    }

    /**
     * Gets the scope of (transitive) dependencies that should be collected. Dependency collection refers to the process
     * of calculating the complete dependency tree in terms of artifact coordinates. In contrast to dependency
     * resolution, this does not include the download of the files for the dependency artifacts. It is meant for mojos
     * that only want to analyze the set of transitive dependencies, in particular during early lifecycle phases where
     * full dependency resolution might fail due to projects which haven't been built yet.
     *
     * @return The scope of (transitive) dependencies that should be collected or {@code null} if none.
     * @since 3.0-alpha-3
     */
    public String getDependencyCollectionRequired()
    {
        return dependencyCollectionRequired;
    }

    // ----------------------------------------------------------------------
    // Project requirement
    // ----------------------------------------------------------------------

    /**
     * @param requiresProject <code>true</code> if the Mojo needs a Maven project to be executed, <code>false</code>
     * otherwise.
     */
    public void setProjectRequired( boolean requiresProject )
    {
        this.projectRequired = requiresProject;
    }

    /**
     * @return <code>true</code> if the Mojo needs a Maven project to be executed, <code>false</code> otherwise.
     */
    public boolean isProjectRequired()
    {
        return projectRequired;
    }

    // ----------------------------------------------------------------------
    // Online vs. Offline requirement
    // ----------------------------------------------------------------------

    /**
     * @param requiresOnline <code>true</code> if the Mojo is online, <code>false</code> otherwise.
     */
    public void setOnlineRequired( boolean requiresOnline )
    {
        this.onlineRequired = requiresOnline;
    }

    /**
     * @return <code>true</code> if the Mojo is online, <code>false</code> otherwise.
     */
    // blech! this isn't even intelligible as a method name. provided for
    // consistency...
    public boolean isOnlineRequired()
    {
        return onlineRequired;
    }

    /**
     * @return <code>true</code> if the Mojo is online, <code>false</code> otherwise.
     */
    // more english-friendly method...keep the code clean! :)
    public boolean requiresOnline()
    {
        return onlineRequired;
    }

    /**
     * @return the bound phase name of the Mojo
     */
    public String getPhase()
    {
        return phase;
    }

    /**
     * @param phase the new bound phase name of the Mojo
     */
    public void setPhase( String phase )
    {
        this.phase = phase;
    }

    /**
     * @return the version when the Mojo was added to the API
     */
    public String getSince()
    {
        return since;
    }

    /**
     * @param since the new version when the Mojo was added to the API
     */
    public void setSince( String since )
    {
        this.since = since;
    }

    /**
     * @return The goal name of the Mojo
     */
    public String getGoal()
    {
        return goal;
    }

    /**
     * @param goal The new goal name of the Mojo
     */
    public void setGoal( String goal )
    {
        this.goal = goal;
    }

    /**
     * @return the invocation phase of the Mojo
     */
    public String getExecutePhase()
    {
        return executePhase;
    }

    /**
     * @param executePhase the new invocation phase of the Mojo
     */
    public void setExecutePhase( String executePhase )
    {
        this.executePhase = executePhase;
    }

    /**
     * @return <code>true</code> if the Mojo uses <code>always</code> for the <code>executionStrategy</code>
     */
    public boolean alwaysExecute()
    {
        return MULTI_PASS_EXEC_STRATEGY.equals( executionStrategy );
    }

    /**
     * @return the execution strategy
     */
    public String getExecutionStrategy()
    {
        return executionStrategy;
    }

    /**
     * @param executionStrategy the new execution strategy
     */
    public void setExecutionStrategy( String executionStrategy )
    {
        this.executionStrategy = executionStrategy;
    }

    /**
     * @return the mojo configuration
     */
    public PlexusConfiguration getMojoConfiguration()
    {
        if ( mojoConfiguration == null )
        {
            mojoConfiguration = new XmlPlexusConfiguration( "configuration" );
        }
        return mojoConfiguration;
    }

    /**
     * @param mojoConfiguration a new mojo configuration
     */
    public void setMojoConfiguration( PlexusConfiguration mojoConfiguration )
    {
        this.mojoConfiguration = mojoConfiguration;
    }

    /** {@inheritDoc} */
    public String getRole()
    {
        return Mojo.ROLE;
    }

    /** {@inheritDoc} */
    public String getRoleHint()
    {
        return getId();
    }

    /**
     * @return the id of the mojo, based on the goal name
     */
    public String getId()
    {
        return getPluginDescriptor().getId() + ":" + getGoal();
    }

    /**
     * @return the full goal name
     * @see PluginDescriptor#getGoalPrefix()
     * @see #getGoal()
     */
    public String getFullGoalName()
    {
        return getPluginDescriptor().getGoalPrefix() + ":" + getGoal();
    }

    /** {@inheritDoc} */
    public String getComponentType()
    {
        return MAVEN_PLUGIN;
    }

    /**
     * @return the plugin descriptor
     */
    public PluginDescriptor getPluginDescriptor()
    {
        return pluginDescriptor;
    }

    /**
     * @param pluginDescriptor the new plugin descriptor
     */
    public void setPluginDescriptor( PluginDescriptor pluginDescriptor )
    {
        this.pluginDescriptor = pluginDescriptor;
    }

    /**
     * @return <code>true</code> if the Mojo is inherited, <code>false</code> otherwise.
     */
    public boolean isInheritedByDefault()
    {
        return inheritedByDefault;
    }

    /**
     * @param inheritedByDefault <code>true</code> if the Mojo is inherited, <code>false</code> otherwise.
     */
    public void setInheritedByDefault( boolean inheritedByDefault )
    {
        this.inheritedByDefault = inheritedByDefault;
    }

    /** {@inheritDoc} */
    public boolean equals( Object object )
    {
        if ( this == object )
        {
            return true;
        }

        if ( object instanceof MojoDescriptor )
        {
            MojoDescriptor other = (MojoDescriptor) object;

            return Objects.equals( getPluginDescriptor(), other.getPluginDescriptor() )
                    && Objects.equals( getGoal(), other.getGoal() );
        }

        return false;
    }

    /** {@inheritDoc} */
    public int hashCode()
    {
        return Objects.hash( getGoal(), getPluginDescriptor() );
    }

    /**
     * @return the invocation lifecycle of the Mojo
     */
    public String getExecuteLifecycle()
    {
        return executeLifecycle;
    }

    /**
     * @param executeLifecycle the new invocation lifecycle of the Mojo
     */
    public void setExecuteLifecycle( String executeLifecycle )
    {
        this.executeLifecycle = executeLifecycle;
    }

    /**
     * @param aggregator <code>true</code> if the Mojo uses the Maven project and its child modules,
     * <code>false</code> otherwise.
     */
    public void setAggregator( boolean aggregator )
    {
        this.aggregator = aggregator;
    }

    /**
     * @return <code>true</code> if the Mojo uses the Maven project and its child modules,
     * <code>false</code> otherwise.
     */
    public boolean isAggregator()
    {
        return aggregator;
    }

    /**
     * @return <code>true</code> if the Mojo cannot be invoked directly, <code>false</code> otherwise.
     */
    public boolean isDirectInvocationOnly()
    {
        return directInvocationOnly;
    }

    /**
     * @param directInvocationOnly <code>true</code> if the Mojo cannot be invoked directly,
     * <code>false</code> otherwise.
     */
    public void setDirectInvocationOnly( boolean directInvocationOnly )
    {
        this.directInvocationOnly = directInvocationOnly;
    }

    /**
     * @return <code>true</code> if the Mojo needs reports to run, <code>false</code> otherwise.
     */
    public boolean isRequiresReports()
    {
        return requiresReports;
    }

    /**
     * @param requiresReports <code>true</code> if the Mojo needs reports to run, <code>false</code> otherwise.
     */
    public void setRequiresReports( boolean requiresReports )
    {
        this.requiresReports = requiresReports;
    }

    /**
     * @param executeGoal the new invocation goal of the Mojo
     */
    public void setExecuteGoal( String executeGoal )
    {
        this.executeGoal = executeGoal;
    }

    /**
     * @return the invocation goal of the Mojo
     */
    public String getExecuteGoal()
    {
        return executeGoal;
    }


    /**
     * @return True if the <code>Mojo</code> is thread-safe and can be run safely in parallel
     * @since 3.0-beta-2
     */
    public boolean isThreadSafe()
    {
        return threadSafe;
    }

    /**
     * @param threadSafe indicates that the mojo is thread-safe and can be run safely in parallel
     * @since 3.0-beta-2
     */
    public void setThreadSafe( boolean threadSafe )
    {
        this.threadSafe = threadSafe;
    }

    /**
     * @return {@code true} if this mojo forks either a goal or the lifecycle, {@code false} otherwise.
     */
    public boolean isForking()
    {
        return ( getExecuteGoal() != null && getExecuteGoal().length() > 0 )
            || ( getExecutePhase() != null && getExecutePhase().length() > 0 );
    }

    /**
     * Creates a shallow copy of this mojo descriptor.
     */
    @Override
    public MojoDescriptor clone()
    {
        try
        {
            return (MojoDescriptor) super.clone();
        }
        catch ( CloneNotSupportedException e )
        {
            throw new UnsupportedOperationException( e );
        }
    }

}
