package org.apache.maven.reporting.exec;

/*
 * 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.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
import org.apache.maven.artifact.repository.RepositoryRequest;
import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoNotFoundException;
import org.apache.maven.plugin.PluginConfigurationException;
import org.apache.maven.plugin.PluginContainerException;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
import org.apache.maven.plugin.version.PluginVersionRequest;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.plugin.version.PluginVersionResolver;
import org.apache.maven.plugin.version.PluginVersionResult;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.MavenReport;
import org.codehaus.classworlds.ClassRealm;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomUtils;
import org.sonatype.aether.repository.RemoteRepository;
import org.sonatype.aether.util.filter.ExclusionsDependencyFilter;

/**
 * <p>
 *   This component will build some {@link MavenReportExecution} from {@link MavenReportExecutorRequest}.
 *   If a {@link MavenReport} need to fork a lifecycle, this fork is executed here. 
 *   It will ask the core to get some informations in order to correctly setup {@link MavenReport}.
 * </p>
 * <p>
 *   <b>Note</b> if no version is defined in the report plugin the version will be search 
 *   with method {@link #getPluginVersion(ReportPlugin, RepositoryRequest, MavenReportExecutorRequest)}
 *   Steps to find a plugin version stop after each step if a non <code>null</code> value has been found:
 *   <ul>
 *     <li>use the one defined in the reportPlugin configuration</li>
 *     <li>search similar (same groupId and artifactId) mojo in the build/plugins section of the pom</li>
 *     <li>search similar (same groupId and artifactId) mojo in the build/pluginManagement section of the pom</li>
 *     <li>ask {@link PluginVersionResolver} to get a version and display a warning as it's not a recommended use</li>  
 *   </ul>
 * </p>
 * <p>
 *   Following steps are done
 *   <ul>
 *     <li>get {@link PluginDescriptor} from the {@link MavenPluginManager#getPluginDescriptor(Plugin, RepositoryRequest)}</li>
 *     <li>setup a {@link ClassLoader} with the Mojo Site plugin {@link ClassLoader} as parent for the report execution. 
 *       You must note some classes are imported from the current Site Mojo {@link ClassRealm} see {@link #IMPORTS}.
 *       The artifact resolution excludes the following artifacts (with using an {@link ExclusionSetFilter}: 
 *       doxia-site-renderer, doxia-sink-api, maven-reporting-api.
 *       done using {@link MavenPluginManager#setupPluginRealm(PluginDescriptor, org.apache.maven.execution.MavenSession, ClassLoader, List, org.apache.maven.artifact.resolver.filter.ArtifactFilter)}
 *     </li>
 *     <li>
 *       setup the mojo using {@link MavenPluginManager#getConfiguredMojo(Class, org.apache.maven.execution.MavenSession, MojoExecution)}
 *     </li>
 *     <li>
 *       verify with {@link LifecycleExecutor#calculateForkedExecutions(MojoExecution, org.apache.maven.execution.MavenSession)}
 *       if any forked execution is needed: if yes executes the forked execution here
 *     </li>
 *   </ul>
 * </p>
 * @author Olivier Lamy
 * @since 3.0-beta-1
 */
@Component( role = MavenReportExecutor.class )
public class DefaultMavenReportExecutor
    implements MavenReportExecutor
{
    @Requirement
    private Logger logger;

    @Requirement
    protected MavenPluginManager mavenPluginManager;

    @Requirement
    protected LifecycleExecutor lifecycleExecutor;

    @Requirement
    protected PluginVersionResolver pluginVersionResolver;

    private static final List<String> IMPORTS = Arrays.asList( "org.apache.maven.reporting.MavenReport",
                                                               "org.apache.maven.reporting.MavenMultiPageReport",
                                                               "org.apache.maven.doxia.siterenderer.Renderer",
                                                               "org.apache.maven.doxia.sink.SinkFactory",
                                                               "org.codehaus.doxia.sink.Sink",
                                                               "org.apache.maven.doxia.sink.Sink",
                                                               "org.apache.maven.doxia.sink.SinkEventAttributes" );

    private static final ExclusionsDependencyFilter EXCLUDES =
        new ExclusionsDependencyFilter( Arrays.asList( "doxia-site-renderer", "doxia-sink-api", "maven-reporting-api" ) );

    public List<MavenReportExecution> buildMavenReports( MavenReportExecutorRequest mavenReportExecutorRequest )
        throws MojoExecutionException
    {
        if ( mavenReportExecutorRequest.getReportPlugins() == null )
        {
            return Collections.emptyList();
        }
        getLog().debug( "DefaultMavenReportExecutor.buildMavenReports()" );

        List<String> reportPluginKeys = new ArrayList<String>();
        List<MavenReportExecution> reports = new ArrayList<MavenReportExecution>();

        String pluginKey = "";
        try
        {
            for ( ReportPlugin reportPlugin : mavenReportExecutorRequest.getReportPlugins() )
            {
                pluginKey = reportPlugin.getGroupId() + ":" + reportPlugin.getArtifactId();

                buildReportPlugin( mavenReportExecutorRequest, reportPlugin, reportPluginKeys, reports );
            }
            return reports;
        }
        catch ( Exception e )
        {
            throw new MojoExecutionException( "failed to get report for " + pluginKey, e );
        }
    }

    protected void buildReportPlugin( MavenReportExecutorRequest mavenReportExecutorRequest, ReportPlugin reportPlugin,
                                      List<String> reportPluginKeys, List<MavenReportExecution> reports )
        throws Exception
    {
        Plugin plugin = new Plugin();
        plugin.setGroupId( reportPlugin.getGroupId() );
        plugin.setArtifactId( reportPlugin.getArtifactId() );

        String pluginKey = reportPlugin.getGroupId() + ":" + reportPlugin.getArtifactId();
        if ( reportPluginKeys.contains( pluginKey ) )
        {
            logger.info( "plugin " + pluginKey + " will be executed more than one time" );
        }
        else
        {
            reportPluginKeys.add( pluginKey );
        }

        RepositoryRequest repositoryRequest = new DefaultRepositoryRequest();
        repositoryRequest.setLocalRepository( mavenReportExecutorRequest.getLocalRepository() );
        repositoryRequest.setRemoteRepositories( mavenReportExecutorRequest.getProject().getPluginArtifactRepositories() );

        plugin.setVersion( getPluginVersion( reportPlugin, repositoryRequest, mavenReportExecutorRequest ) );

        mergePluginToReportPlugin( mavenReportExecutorRequest, plugin, reportPlugin );

        logger.info( "configuring report plugin " + plugin.getId() );

        MavenSession session = mavenReportExecutorRequest.getMavenSession();
        List<RemoteRepository> remoteRepositories = session.getCurrentProject().getRemotePluginRepositories();

        PluginDescriptor pluginDescriptor =
            mavenPluginManager.getPluginDescriptor( plugin, remoteRepositories, session.getRepositorySession() );

        Map<String, PlexusConfiguration> goalsWithConfiguration = new LinkedHashMap<String, PlexusConfiguration>();

        if ( reportPlugin.getReportSets().isEmpty() && reportPlugin.getReports().isEmpty() )
        {
            List<MojoDescriptor> mojoDescriptors = pluginDescriptor.getMojos();
            for ( MojoDescriptor mojoDescriptor : mojoDescriptors )
            {
                goalsWithConfiguration.put( mojoDescriptor.getGoal(), mojoDescriptor.getConfiguration() );
            }
        }
        else
        {
            for ( ReportSet reportSet : reportPlugin.getReportSets() )
            {
                for ( String report : reportSet.getReports() )
                {
                    goalsWithConfiguration.put( report, reportSet.getConfiguration() );
                }
            }

            for ( String report : reportPlugin.getReports() )
            {
                goalsWithConfiguration.put( report, reportPlugin.getConfiguration() );
            }
        }

        for ( Entry<String, PlexusConfiguration> entry : goalsWithConfiguration.entrySet() )
        {
            MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( entry.getKey() );
            if ( mojoDescriptor == null )
            {
                throw new MojoNotFoundException( entry.getKey(), pluginDescriptor );
            }

            MojoExecution mojoExecution = new MojoExecution( plugin, entry.getKey(), "report:" + entry.getKey() );

            mojoExecution.setConfiguration( convert( mojoDescriptor ) );

            if ( reportPlugin.getConfiguration() != null || entry.getValue() != null )
            {
                Xpp3Dom reportConfiguration =
                    reportPlugin.getConfiguration() == null ? new Xpp3Dom( "fake" )
                                    : convert( reportPlugin.getConfiguration() );

                // MSITE-512 configuration from ReportSet must win
                Xpp3Dom mergedConfigurationWithReportSet =
                    Xpp3DomUtils.mergeXpp3Dom( convert( entry.getValue() ), reportConfiguration );

                Xpp3Dom mergedConfiguration =
                    Xpp3DomUtils.mergeXpp3Dom( mergedConfigurationWithReportSet, convert( mojoDescriptor ) );

                Xpp3Dom cleanedConfiguration = new Xpp3Dom( "configuration" );
                if ( mergedConfiguration.getChildren() != null )
                {
                    for ( Xpp3Dom parameter : mergedConfiguration.getChildren() )
                    {
                        if ( mojoDescriptor.getParameterMap().containsKey( parameter.getName() ) )
                        {
                            cleanedConfiguration.addChild( parameter );
                        }
                    }
                }
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "mojoExecution mergedConfiguration: " + mergedConfiguration );
                    getLog().debug( "mojoExecution cleanedConfiguration: " + cleanedConfiguration );
                }

                mojoExecution.setConfiguration( cleanedConfiguration );
            }

            mojoExecution.setMojoDescriptor( mojoDescriptor );

            mavenPluginManager.setupPluginRealm( pluginDescriptor, mavenReportExecutorRequest.getMavenSession(),
                                                 Thread.currentThread().getContextClassLoader(), IMPORTS, EXCLUDES );
            MavenReport mavenReport =
                getConfiguredMavenReport( mojoExecution, pluginDescriptor, mavenReportExecutorRequest );

            if ( mavenReport == null )
            {
                continue;
            }

            MavenReportExecution mavenReportExecution =
                new MavenReportExecution( mojoExecution.getPlugin(), mavenReport, pluginDescriptor.getClassRealm() );

            lifecycleExecutor.calculateForkedExecutions( mojoExecution, mavenReportExecutorRequest.getMavenSession() );

            if ( !mojoExecution.getForkedExecutions().isEmpty() )
            {
                lifecycleExecutor.executeForkedExecutions( mojoExecution, mavenReportExecutorRequest.getMavenSession() );
            }

            if ( canGenerateReport( mavenReport, mojoExecution ) )
            {
                reports.add( mavenReportExecution );
            }
        }
    }

    private boolean canGenerateReport( MavenReport mavenReport, MojoExecution mojoExecution )
    {
        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
        try
        {
            Thread.currentThread().setContextClassLoader( mojoExecution.getMojoDescriptor().getRealm() );

            return mavenReport.canGenerateReport();
        }
        finally
        {
            Thread.currentThread().setContextClassLoader( originalClassLoader );
        } 
    }

    private MavenReport getConfiguredMavenReport( MojoExecution mojoExecution, PluginDescriptor pluginDescriptor,
                                                  MavenReportExecutorRequest mavenReportExecutorRequest )
        throws PluginContainerException, PluginConfigurationException
    {
        try
        {
            if ( !isMavenReport( mojoExecution, pluginDescriptor ) )
            {
                return null;
            }

            Mojo mojo = mavenPluginManager.getConfiguredMojo( Mojo.class,
                                                              mavenReportExecutorRequest.getMavenSession(),
                                                              mojoExecution );

            return (MavenReport) mojo;
        }
        catch ( ClassCastException e )
        {
            getLog().warn( "skip ClassCastException " + e.getMessage() );
            return null;
        }
        catch ( PluginContainerException e )
        {
            /**
             * ignore old plugin which are using removed PluginRegistry
             * [INFO] Caused by: java.lang.NoClassDefFoundError: org/apache/maven/plugin/registry/PluginRegistry
             */
            if ( e.getCause() != null && e.getCause() instanceof NoClassDefFoundError
                && e.getMessage().contains( "PluginRegistry" ) )
            {
                getLog().warn( "skip NoClassDefFoundError with PluginRegistry " );
                // too noisy, only in debug mode + e.getMessage() );
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( e.getMessage(), e );
                }
                return null;
            }
            throw e;
        }
    }

    private boolean isMavenReport( MojoExecution mojoExecution, PluginDescriptor pluginDescriptor )
    {
        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
        Class<?> mojoClass;
        Thread.currentThread().setContextClassLoader( mojoExecution.getMojoDescriptor().getRealm() );
        try
        {
            mojoClass =
                pluginDescriptor.getClassRealm().loadClass( mojoExecution.getMojoDescriptor().getImplementation() );
        }
        catch ( ClassNotFoundException e )
        {
            getLog().warn( "skip ClassNotFoundException mojoExecution.goal '" + mojoExecution.getGoal() + "': "
                               + e.getMessage(), e );
            return false;
        }
        finally
        {
            Thread.currentThread().setContextClassLoader( originalClassLoader );
        }       

        try
        {
            Thread.currentThread().setContextClassLoader( mojoExecution.getMojoDescriptor().getRealm() );
            MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( mojoExecution.getGoal() );

            boolean isMavenReport = MavenReport.class.isAssignableFrom( mojoClass );

            if ( getLog().isDebugEnabled() )
            {
                if ( mojoDescriptor != null && mojoDescriptor.getImplementationClass() != null )
                {
                    getLog().debug( "class " + mojoDescriptor.getImplementationClass().getName() + " isMavenReport: "
                                        + isMavenReport );
                }

                if ( !isMavenReport )
                {
                    getLog().debug( "skip non MavenReport " + mojoExecution.getMojoDescriptor().getId() );
                }
            }

            return isMavenReport;
        }
        catch ( LinkageError e )
        {
            getLog().warn( "skip LinkageError mojoExecution.goal '" + mojoExecution.getGoal() + "': " + e.getMessage(),
                           e );
            return false;
        }
        finally
        {
            Thread.currentThread().setContextClassLoader( originalClassLoader );
        }
    }

    private Xpp3Dom convert( MojoDescriptor mojoDescriptor )
    {
        PlexusConfiguration config = mojoDescriptor.getMojoConfiguration();
        return ( config != null ) ? convert( config ) : new Xpp3Dom( "configuration" );
    }

    private Xpp3Dom convert( PlexusConfiguration config )
    {
        if ( config == null )
        {
            return null;
        }

        Xpp3Dom dom = new Xpp3Dom( config.getName() );
        dom.setValue( config.getValue( null ) );

        for ( String attrib : config.getAttributeNames() )
        {
            dom.setAttribute( attrib, config.getAttribute( attrib, null ) );
        }

        for ( int n = config.getChildCount(), i = 0; i < n; i++ )
        {
            dom.addChild( convert( config.getChild( i ) ) );
        }

        return dom;
    }

    private Logger getLog()
    {
        return logger;
    }

    /**
     * Resolve report plugin version. 
     * Steps to find a plugin version stop after each step if a non <code>null</code> value has been found:
     * <ol>
     *   <li>use the one defined in the reportPlugin configuration</li>
     *   <li>search similar (same groupId and artifactId) mojo in the build/plugins section of the pom</li>
     *   <li>search similar (same groupId and artifactId) mojo in the build/pluginManagement section of the pom</li>
     *   <li>ask {@link PluginVersionResolver} to get a version and display a warning as it's not a recommended use</li>  
     * </ol>
     *
     * @param reportPlugin the report plugin to resolve the version
     * @param repositoryRequest TODO: unused, to be removed?
     * @param mavenReportExecutorRequest the current report execution context
     * @return the report plugin version
     * @throws PluginVersionResolutionException
     */
    protected String getPluginVersion( ReportPlugin reportPlugin, RepositoryRequest repositoryRequest,
                                       MavenReportExecutorRequest mavenReportExecutorRequest )
        throws PluginVersionResolutionException
    {
        String reportPluginKey = reportPlugin.getGroupId() + ':' + reportPlugin.getArtifactId();
        if ( getLog().isDebugEnabled() )
        {
            getLog().debug( "resolving version for " + reportPluginKey );
        }

        // look for version defined in the reportPlugin configuration
        if ( reportPlugin.getVersion() != null )
        {
            if ( getLog().isDebugEnabled() )
            {
                logger.debug( "resolved " + reportPluginKey + " version from the reporting.plugins section: "
                    + reportPlugin.getVersion() );
            }
            return reportPlugin.getVersion();
        }

        MavenProject project = mavenReportExecutorRequest.getProject();

        // search in the build section
        if ( project.getBuild() != null )
        {
            Plugin plugin = find( reportPlugin, project.getBuild().getPlugins() );

            if ( plugin != null && plugin.getVersion() != null )
            {
                if ( getLog().isDebugEnabled() )
                {
                    logger.debug( "resolved " + reportPluginKey + " version from the build.plugins section: "
                        + plugin.getVersion() );
                }
                return plugin.getVersion();
            }
        }

        // search in pluginManagement section
        if ( project.getBuild() != null && project.getBuild().getPluginManagement() != null )
        {
            Plugin plugin = find( reportPlugin, project.getBuild().getPluginManagement().getPlugins() );

            if ( plugin != null && plugin.getVersion() != null )
            {
                if ( getLog().isDebugEnabled() )
                {
                    logger.debug( "resolved " + reportPluginKey
                        + " version from the build.pluginManagement.plugins section: " + plugin.getVersion() );
                }
                return plugin.getVersion();
            }
        }


        logger.warn( "Report plugin " + reportPluginKey + " has an empty version." );
        logger.warn( "" );
        logger.warn( "It is highly recommended to fix these problems"
            + " because they threaten the stability of your build." );
        logger.warn( "" );
        logger.warn( "For this reason, future Maven versions might no"
            + " longer support building such malformed projects." );

        Plugin plugin = new Plugin();
        plugin.setGroupId( reportPlugin.getGroupId() );
        plugin.setArtifactId( reportPlugin.getArtifactId() );
        
        PluginVersionRequest pluginVersionRequest =
            new DefaultPluginVersionRequest( plugin, mavenReportExecutorRequest.getMavenSession() );

        PluginVersionResult result = pluginVersionResolver.resolve( pluginVersionRequest );
        if ( getLog().isDebugEnabled() )
        {
            getLog().debug( "resolved " + reportPluginKey + " version from repository: " + result.getVersion() );
        }
        return result.getVersion();
    }

    /**
     * Search similar (same groupId and artifactId) mojo as a given report plugin.
     * 
     * @param reportPlugin the report plugin to search for a similar mojo
     * @param plugins the candidate mojos 
     * @return the first similar mojo
     */
    private Plugin find( ReportPlugin reportPlugin, List<Plugin> plugins )
    {
        if ( plugins == null )
        {
            return null;
        }
        for ( Plugin plugin : plugins )
        {
            if ( StringUtils.equals( plugin.getArtifactId(), reportPlugin.getArtifactId() )
                && StringUtils.equals( plugin.getGroupId(), reportPlugin.getGroupId() ) )
            {
                return plugin;
            }
        }
        return null;
    }

    /**
     * TODO other stuff to merge ?
     * <p>
     * this method will "merge" some part of the plugin declaration existing in the build section 
     * to the fake plugin build for report execution:
     * <ul>
     *   <li>dependencies</li>
     * </ul>
     * </p>
     * @param mavenReportExecutorRequest
     * @param buildPlugin
     * @param reportPlugin
     */
    private void mergePluginToReportPlugin( MavenReportExecutorRequest mavenReportExecutorRequest, Plugin buildPlugin,
                                            ReportPlugin reportPlugin )
    {
        Plugin configuredPlugin = find( reportPlugin, mavenReportExecutorRequest.getProject().getBuild().getPlugins() );
        if ( configuredPlugin != null )
        {
            if ( !configuredPlugin.getDependencies().isEmpty() )
            {
                buildPlugin.getDependencies().addAll( configuredPlugin.getDependencies() );
            }
        }
    }   
}
