package org.apache.maven.project.collector;

/*
 * 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.MavenExecutionRequest;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.building.ModelProblem;
import org.apache.maven.model.locator.ModelLocator;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingResult;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.transfer.ArtifactNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

/**
 * Strategy for collecting Maven projects from the multi-module project root, even when executed in a submodule.
 */
@Named( "MultiModuleCollectionStrategy" )
@Singleton
public class MultiModuleCollectionStrategy implements ProjectCollectionStrategy
{
    private final Logger logger = LoggerFactory.getLogger( getClass() );
    private final ModelLocator modelLocator;
    private final ProjectsSelector projectsSelector;

    @Inject
    public MultiModuleCollectionStrategy( ModelLocator modelLocator, ProjectsSelector projectsSelector )
    {
        this.modelLocator = modelLocator;
        this.projectsSelector = projectsSelector;
    }

    @Override
    public List<MavenProject> collectProjects( MavenExecutionRequest request ) throws ProjectBuildingException
    {
        File moduleProjectPomFile = getMultiModuleProjectPomFile( request );
        List<File> files = Collections.singletonList( moduleProjectPomFile.getAbsoluteFile() );
        try
        {
            List<MavenProject> projects = projectsSelector.selectProjects( files, request );
            boolean isRequestedProjectCollected = isRequestedProjectCollected( request, projects );
            if ( isRequestedProjectCollected )
            {
                return projects;
            }
            else
            {
                logger.debug( "Multi module project collection failed:{}"
                        + "Detected a POM file next to a .mvn folder in a parent directory ({}). "
                        + "Maven assumed that POM file to be the parent of the requested project ({}), but it turned "
                        + "out that it was not. Another project collection strategy will be executed as result.",
                        System.lineSeparator(), moduleProjectPomFile.getAbsolutePath(),
                        request.getPom().getAbsolutePath() );
                return Collections.emptyList();
            }
        }
        catch ( ProjectBuildingException e )
        {
            boolean fallThrough = isModuleOutsideRequestScopeDependingOnPluginModule( request, e );

            if ( fallThrough )
            {
                logger.debug( "Multi module project collection failed:{}"
                        + "Detected that one of the modules of this multi module project uses another module as "
                        + "plugin extension which still needed to be built. This is not possible within the same "
                        + "reactor build. Another project collection strategy will be executed as result.",
                        System.lineSeparator() );
                return Collections.emptyList();
            }

            throw e;
        }
    }

    private File getMultiModuleProjectPomFile( MavenExecutionRequest request )
    {
        if ( request.getPom().getParentFile().equals( request.getMultiModuleProjectDirectory() ) )
        {
            return request.getPom();
        }
        else
        {
            File multiModuleProjectPom = modelLocator.locatePom( request.getMultiModuleProjectDirectory() );
            if ( !multiModuleProjectPom.exists() )
            {
                logger.info( "Maven detected that the requested POM file is part of a multi module project, "
                        + "but could not find a pom.xml file in the multi module root directory '{}'.",
                        request.getMultiModuleProjectDirectory() );
                logger.info( "The reactor is limited to all projects under: " + request.getPom().getParent() );
                return request.getPom();
            }

            return multiModuleProjectPom;
        }
    }

    /**
     * multiModuleProjectDirectory in MavenExecutionRequest is not always the parent of the request pom.
     * We should always check whether the request pom project is collected.
     * The integration tests for MNG-6223 are examples for this scenario.
     *
     * @return true if the collected projects contain the requested project (for example with -f)
     */
    private boolean isRequestedProjectCollected( MavenExecutionRequest request, List<MavenProject> projects )
    {
        return projects.stream()
                .map( MavenProject::getFile )
                .anyMatch( request.getPom()::equals );
    }

    /**
     * This method finds out whether collecting projects failed because of the following scenario:
     * - A multi module project containing a module which is a plugin and another module which depends on it.
     * - Just the plugin is being built with the -f <pom> flag.
     * - Because of inter-module dependency collection, all projects in the multi-module project are collected.
     * - The plugin is not yet installed in a repository.
     *
     * Therefore the build fails because the plugin is not found and plugins cannot be built in the same session.
     *
     * The integration test for <a href="https://issues.apache.org/jira/browse/MNG-5572">MNG-5572</a> is an
     *   example of this scenario.
     *
     * @return true if the module which fails to collect the inter-module plugin is not part of the build.
     */
    private boolean isModuleOutsideRequestScopeDependingOnPluginModule( MavenExecutionRequest request,
                                                                        ProjectBuildingException exception )
    {
        return exception.getResults().stream()
                .map( ProjectBuildingResult::getProject )
                .filter( Objects::nonNull )
                .filter( project -> request.getPom().equals( project.getFile() ) )
                .findFirst()
                .map( requestPomProject ->
                {
                    List<MavenProject> modules = requestPomProject.getCollectedProjects() != null
                            ? requestPomProject.getCollectedProjects() : Collections.emptyList();
                    List<MavenProject> projectsInRequestScope = new ArrayList<>( modules );
                    projectsInRequestScope.add( requestPomProject );

                    Predicate<ProjectBuildingResult> projectsOutsideOfRequestScope =
                            pr -> !projectsInRequestScope.contains( pr.getProject() );

                    Predicate<Exception> pluginArtifactNotFoundException =
                            exc -> exc instanceof PluginManagerException
                                    && exc.getCause() instanceof PluginResolutionException
                                    && exc.getCause().getCause() instanceof ArtifactResolutionException
                                    && exc.getCause().getCause().getCause() instanceof ArtifactNotFoundException;

                    Predicate<Plugin> isPluginPartOfRequestScope = plugin -> projectsInRequestScope.stream()
                            .anyMatch( project -> project.getGroupId().equals( plugin.getGroupId() )
                                    && project.getArtifactId().equals( plugin.getArtifactId() )
                                    && project.getVersion().equals( plugin.getVersion() ) );

                    return exception.getResults().stream()
                            .filter( projectsOutsideOfRequestScope )
                            .flatMap( projectBuildingResult -> projectBuildingResult.getProblems().stream() )
                            .map( ModelProblem::getException )
                            .filter( pluginArtifactNotFoundException )
                            .map( exc -> ( ( PluginResolutionException ) exc.getCause() ).getPlugin() )
                            .anyMatch( isPluginPartOfRequestScope );
                } ).orElse( false );
    }
}
