package org.apache.maven.shared.artifact.filter.collection;

/*
 * 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.RepositoryUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.DependencyResolutionResult;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingResult;

import java.lang.reflect.InvocationTargetException;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * This filter will exclude everything that is not a dependency of the selected artifact.
 *
 * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
 * @version $Id$
 */
public class ArtifactTransitivityFilter
    extends AbstractArtifactsFilter
{
    /**
     * List of dependencyConflictIds of transitiveArtifacts
     */
    private Set<String> transitiveArtifacts;

    /**
     * <p>
     * Use {@link org.apache.maven.execution.MavenSession#getProjectBuildingRequest()} to get the buildingRequest.
     * The projectBuilder should be resolved with CDI.
     * </p>
     * <pre>
     *   // For Mojo
     *   &#64;Component
     *   private ProjectBuilder projectBuilder;
     *
     *   // For Components
     *   &#64;Requirement // or &#64;Inject
     *   private ProjectBuilder projectBuilder;
     * </pre>
     *
     * @param artifact        the artifact to resolve the dependencies from
     * @param buildingRequest the buildingRequest
     * @param projectBuilder  the projectBuilder
     * @throws ProjectBuildingException if the project descriptor could not be successfully built
     */
    public ArtifactTransitivityFilter( Artifact artifact, ProjectBuildingRequest buildingRequest,
                                       ProjectBuilder projectBuilder )
        throws ProjectBuildingException
    {
        ProjectBuildingRequest request = new DefaultProjectBuildingRequest( buildingRequest );

        request.setResolveDependencies( true );

        ProjectBuildingResult buildingResult = projectBuilder.build( artifact, request );

        DependencyResolutionResult resolutionResult = buildingResult.getDependencyResolutionResult();
        if ( resolutionResult != null )
        {
            if ( isMaven31() )
            {
                try
                {
                    @SuppressWarnings( "unchecked" ) List<org.eclipse.aether.graph.Dependency> dependencies =
                        (List<org.eclipse.aether.graph.Dependency>) Invoker.invoke( resolutionResult,
                                                                                    "getDependencies" );

                    for ( org.eclipse.aether.graph.Dependency dependency : dependencies )
                    {
                        Artifact mavenArtifact = 
                                        (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact",
                                                                    org.eclipse.aether.artifact.Artifact.class,
                                                                    dependency.getArtifact() );

                        transitiveArtifacts.add( mavenArtifact.getDependencyConflictId() );
                    }
                }
                catch ( IllegalAccessException e )
                {
                    // don't want to pollute method signature with ReflectionExceptions
                    throw new RuntimeException( e.getMessage(), e );
                }
                catch ( InvocationTargetException e )
                {
                    // don't want to pollute method signature with ReflectionExceptions
                    throw new RuntimeException( e.getMessage(), e );
                }
                catch ( NoSuchMethodException e )
                {
                    // don't want to pollute method signature with ReflectionExceptions
                    throw new RuntimeException( e.getMessage(), e );
                }
            }
            else
            {
                try
                {
                    @SuppressWarnings( "unchecked" ) List<org.sonatype.aether.graph.Dependency> dependencies =
                        (List<org.sonatype.aether.graph.Dependency>) Invoker.invoke( resolutionResult,
                                                                                     "getDependencies" );

                    for ( org.sonatype.aether.graph.Dependency dependency : dependencies )
                    {
                        Artifact mavenArtifact = 
                                        (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact",
                                                                    org.sonatype.aether.artifact.Artifact.class,
                                                                    dependency.getArtifact() );

                        transitiveArtifacts.add( mavenArtifact.getDependencyConflictId() );
                    }
                }
                catch ( IllegalAccessException e )
                {
                    // don't want to pollute method signature with ReflectionExceptions
                    throw new RuntimeException( e.getMessage(), e );
                }
                catch ( InvocationTargetException e )
                {
                    // don't want to pollute method signature with ReflectionExceptions
                    throw new RuntimeException( e.getMessage(), e );
                }
                catch ( NoSuchMethodException e )
                {
                    // don't want to pollute method signature with ReflectionExceptions
                    throw new RuntimeException( e.getMessage(), e );
                }
            }
        }
    }

    /**
     * @return true if the current Maven version is Maven 3.1.
     */
    protected static boolean isMaven31()
    {
        return canFindCoreClass( "org.eclipse.aether.artifact.Artifact" ); // Maven 3.1 specific
    }

    private static boolean canFindCoreClass( String className )
    {
        try
        {
            Thread.currentThread().getContextClassLoader().loadClass( className );

            return true;
        }
        catch ( ClassNotFoundException e )
        {
            return false;
        }
    }

    /**
     * {@inheritDoc}
     */
    public Set<Artifact> filter( Set<Artifact> artifacts )
    {

        Set<Artifact> result = new LinkedHashSet<Artifact>();
        for ( Artifact artifact : artifacts )
        {
            if ( artifactIsATransitiveDependency( artifact ) )
            {
                result.add( artifact );
            }
        }
        return result;
    }

    /**
     * Compares the artifact to the list of dependencies to see if it is directly included by this project
     *
     * @param artifact representing the item to compare.
     * @return true if artifact is a transitive dependency
     */
    public boolean artifactIsATransitiveDependency( Artifact artifact )
    {
        return transitiveArtifacts.contains( artifact.getDependencyConflictId() );
    }
}
