package org.apache.maven.plugins.enforcer;

/*
 * 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.Collections;
import java.util.List;

import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.enforcer.rule.api.EnforcerRule;
import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugins.enforcer.utils.ArtifactMatcher;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.shared.dependency.graph.DependencyNode;
import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyGraphBuilder;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.logging.console.ConsoleLogger;

/**
 * This rule bans all transitive dependencies. There is a configuration option to exclude certain artifacts from being
 * checked.
 * 
 * @author Jakub Senko
 */
public class BanTransitiveDependencies
    extends AbstractNonCacheableEnforcerRule
    implements EnforcerRule
{

    private EnforcerRuleHelper helper;

    /**
     * Specify the dependencies that will be ignored. This can be a list of artifacts in the format
     * <code>groupId[:artifactId][:version][:type][:scope]</code>. Wildcard '*' can be used to in place of specific
     * section (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0') <br>
     * You can override this patterns by using includes. Version is a string representing standard maven version range.
     * Empty patterns will be ignored.
     */
    private List<String> excludes;

    /**
     * Specify the dependencies that will be checked. These are exceptions to excludes intended for more convenient and
     * finer settings. This can be a list of artifacts in the format
     * <code>groupId[:artifactId][:version][:type][:scope]</code>. Wildcard '*' can be used to in place of specific
     * section (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0') <br>
     * Version is a string representing standard maven version range. Empty patterns will be ignored.
     */
    private List<String> includes;

    /**
     * Searches dependency tree recursively for transitive dependencies that are not excluded, while generating nice
     * info message along the way.
     * 
     * @throws InvalidVersionSpecificationException
     */
    private static boolean searchTree( DependencyNode node, int level, ArtifactMatcher excludes, StringBuilder message )
        throws InvalidVersionSpecificationException
    {

        List<DependencyNode> children = node.getChildren();

        /*
         * if the node is deeper than direct dependency and is empty, it is transitive.
         */
        boolean hasTransitiveDependencies = level > 1;

        boolean excluded = false;

        /*
         * holds recursive message from children, will be appended to current message if this node has any transitive
         * descendants if message is null, don't generate recursive message.
         */
        StringBuilder messageFromChildren = message == null ? null : new StringBuilder();

        if ( excludes.match( node.getArtifact() ) )
        {
            // is excluded, we don't care about descendants
            excluded = true;
            hasTransitiveDependencies = false;
        }
        else
        {
            for ( DependencyNode childNode : children )
            {
                /*
                 * if any of the children has transitive d. so does the parent
                 */
                hasTransitiveDependencies =
                    ( searchTree( childNode, level + 1, excludes, messageFromChildren ) || hasTransitiveDependencies );
            }
        }

        if ( ( excluded || hasTransitiveDependencies ) && message != null ) // then generate message
        {
            for ( int i = 0; i < level; i++ )
            {
                message.append( "   " );
            }

            message.append( node.getArtifact() );

            if ( excluded )
            {
                message.append( " [excluded]" + System.lineSeparator() );
            }

            if ( hasTransitiveDependencies )
            {
                if ( level == 1 )
                {
                    message.append( " has transitive dependencies:" );
                }

                message.append( System.lineSeparator() ).append( messageFromChildren );
            }
        }

        return hasTransitiveDependencies;
    }

    @Override
    public void execute( EnforcerRuleHelper helper )
        throws EnforcerRuleException
    {
        this.helper = helper;

        if ( excludes == null )
        {
            excludes = Collections.emptyList();
        }
        if ( includes == null )
        {
            includes = Collections.emptyList();
        }

        final ArtifactMatcher exclusions = new ArtifactMatcher( excludes, includes );

        DependencyNode rootNode = null;

        try
        {
            MavenProject project = (MavenProject) helper.evaluate( "${project}" );
            MavenSession session = (MavenSession) helper.evaluate( "${session}" );
            
            ProjectBuildingRequest buildingRequest =
                new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
            buildingRequest.setProject( project );
            
            rootNode = createDependencyGraphBuilder().buildDependencyGraph( buildingRequest, null );
        }
        catch ( Exception e )
        {
            throw new EnforcerRuleException( "Error: Could not construct dependency tree.", e );
        }

        String message = getMessage();
        StringBuilder generatedMessage = null;
        if ( message == null )
        {
            generatedMessage = new StringBuilder();
        }

        try
        {
            if ( searchTree( rootNode, 0, exclusions, generatedMessage ) )
            {
                throw new EnforcerRuleException( message == null ? generatedMessage.toString() : message );
            }
        }
        catch ( InvalidVersionSpecificationException e )
        {
            throw new EnforcerRuleException( "Error: Invalid version range.", e );
        }

    }

    private DependencyGraphBuilder createDependencyGraphBuilder()
        throws ComponentLookupException
    {
        // CHECKSTYLE_OFF: LineLength
        DefaultDependencyGraphBuilder builder =
            (DefaultDependencyGraphBuilder) helper.getContainer().lookup( DependencyGraphBuilder.class.getCanonicalName(),
                                                                          "default" );
        // CHECKSTYLE_ON: LineLength

        builder.enableLogging( new ConsoleLogger( ConsoleLogger.LEVEL_DISABLED, "DefaultDependencyGraphBuilder" ) );

        return builder;
    }

}
