package org.apache.maven.shared.dependency.tree;

/*
 * 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.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.ResolutionListener;
import org.apache.maven.artifact.resolver.ResolutionListenerForDepMgmt;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.shared.dependency.tree.traversal.CollectingDependencyNodeVisitor;
import org.codehaus.plexus.logging.Logger;

/**
 * An artifact resolution listener that constructs a dependency tree.
 * 
 * @author Edwin Punzalan
 * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
 * @version $Id$
 */
public class DependencyTreeResolutionListener implements ResolutionListener, ResolutionListenerForDepMgmt
{
    // fields -----------------------------------------------------------------
    
    /**
     * The log to write debug messages to.
     */
    private final Logger logger;

    /**
     * The parent dependency nodes of the current dependency node.
     */
    private final Stack parentNodes;

    /**
     * A map of dependency nodes by their attached artifact.
     */
    private final Map nodesByArtifact;

    /**
     * The root dependency node of the computed dependency tree.
     */
    private DependencyNode rootNode;

    /**
     * The dependency node currently being processed by this listener.
     */
    private DependencyNode currentNode;
    
    /**
     * Map &lt; String replacementId, String premanaged version >
     */
    private Map managedVersions = new HashMap();

    /**
     * Map &lt; String replacementId, String premanaged scope >
     */
    private Map managedScopes = new HashMap();

    // constructors -----------------------------------------------------------

    /**
     * Creates a new dependency tree resolution listener that writes to the specified log.
     * 
     * @param logger
     *            the log to write debug messages to
     */
    public DependencyTreeResolutionListener( Logger logger )
    {
        this.logger = logger;
        
        parentNodes = new Stack();
        nodesByArtifact = new IdentityHashMap();
        rootNode = null;
        currentNode = null;
    }

    // ResolutionListener methods ---------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void testArtifact( Artifact artifact )
    {
        log( "testArtifact: artifact=" + artifact );
    }

    /**
     * {@inheritDoc}
     */
    public void startProcessChildren( Artifact artifact )
    {
        log( "startProcessChildren: artifact=" + artifact );
        
        if ( !currentNode.getArtifact().equals( artifact ) )
        {
            throw new IllegalStateException( "Artifact was expected to be " + currentNode.getArtifact() + " but was "
                            + artifact );
        }

        parentNodes.push( currentNode );
    }

    /**
     * {@inheritDoc}
     */
    public void endProcessChildren( Artifact artifact )
    {
        DependencyNode node = (DependencyNode) parentNodes.pop();

        log( "endProcessChildren: artifact=" + artifact );
        
        if ( node == null )
        {
            throw new IllegalStateException( "Parent dependency node was null" );
        }

        if ( !node.getArtifact().equals( artifact ) )
        {
            throw new IllegalStateException( "Parent dependency node artifact was expected to be " + node.getArtifact()
                            + " but was " + artifact );
        }
    }

    /**
     * {@inheritDoc}
     */
    public void includeArtifact( Artifact artifact )
    {
        log( "includeArtifact: artifact=" + artifact );
        
        DependencyNode existingNode = getNode( artifact );

        /*
         * Ignore duplicate includeArtifact calls since omitForNearer can be called prior to includeArtifact on the same
         * artifact, and we don't wish to include it twice.
         */
        if ( existingNode == null && isCurrentNodeIncluded() )
        {
            DependencyNode node = addNode( artifact );

            /*
             * Add the dependency management information cached in any prior manageArtifact calls, since includeArtifact
             * is always called after manageArtifact.
             */
            flushDependencyManagement( node );
        }
    }

    /**
     * {@inheritDoc}
     */
    public void omitForNearer( Artifact omitted, Artifact kept )
    {
        log( "omitForNearer: omitted=" + omitted + " kept=" + kept );
        
        if ( !omitted.getDependencyConflictId().equals( kept.getDependencyConflictId() ) )
        {
            throw new IllegalArgumentException( "Omitted artifact dependency conflict id "
                            + omitted.getDependencyConflictId() + " differs from kept artifact dependency conflict id "
                            + kept.getDependencyConflictId() );
        }

        if ( isCurrentNodeIncluded() )
        {
            DependencyNode omittedNode = getNode( omitted );

            if ( omittedNode != null )
            {
                removeNode( omitted );
            }
            else
            {
                omittedNode = createNode( omitted );

                currentNode = omittedNode;
            }

            omittedNode.omitForConflict( kept );
            
            /*
             * Add the dependency management information cached in any prior manageArtifact calls, since omitForNearer
             * is always called after manageArtifact.
             */
            flushDependencyManagement( omittedNode );
            
            DependencyNode keptNode = getNode( kept );
            
            if ( keptNode == null )
            {
                addNode( kept );
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void updateScope( Artifact artifact, String scope )
    {
        log( "updateScope: artifact=" + artifact + ", scope=" + scope );
        
        DependencyNode node = getNode( artifact );

        if ( node == null )
        {
            // updateScope events can be received prior to includeArtifact events
            node = addNode( artifact );
        }

        node.setOriginalScope( artifact.getScope() );
    }

    /**
     * {@inheritDoc}
     */
    public void manageArtifact( Artifact artifact, Artifact replacement )
    {
        // TODO: remove when ResolutionListenerForDepMgmt merged into ResolutionListener
        
        log( "manageArtifact: artifact=" + artifact + ", replacement=" + replacement );
        
        if ( replacement.getVersion() != null )
        {
            manageArtifactVersion( artifact, replacement );
        }
        
        if ( replacement.getScope() != null )
        {
            manageArtifactScope( artifact, replacement );
        }
    }

    /**
     * {@inheritDoc}
     */
    public void omitForCycle( Artifact artifact )
    {
        log( "omitForCycle: artifact=" + artifact );
        
        if ( isCurrentNodeIncluded() )
        {
            DependencyNode node = createNode( artifact );

            node.omitForCycle();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void updateScopeCurrentPom( Artifact artifact, String scopeIgnored )
    {
        log( "updateScopeCurrentPom: artifact=" + artifact + ", scopeIgnored=" + scopeIgnored );
        
        DependencyNode node = getNode( artifact );

        if ( node == null )
        {
            // updateScopeCurrentPom events can be received prior to includeArtifact events
            node = addNode( artifact );
            // TODO remove the node that tried to impose its scope and add some info
        }

        node.setFailedUpdateScope( scopeIgnored );
    }

    /**
     * {@inheritDoc}
     */
    public void selectVersionFromRange( Artifact artifact )
    {
        log( "selectVersionFromRange: artifact=" + artifact );

        DependencyNode node = getNode( artifact );

        /*
         * selectVersionFromRange is called before includeArtifact
         */
        if ( node == null && isCurrentNodeIncluded() )
        {
            node = addNode( artifact );
        }

        node.setVersionSelectedFromRange( artifact.getVersionRange() );
        node.setAvailableVersions( artifact.getAvailableVersions() );
    }

    /**
     * {@inheritDoc}
     */
    public void restrictRange( Artifact artifact, Artifact replacement, VersionRange versionRange )
    {
        log( "restrictRange: artifact=" + artifact + ", replacement=" + replacement + ", versionRange=" + versionRange );
        
        // TODO: track range restriction in node (MNG-3093)
    }
    
    // ResolutionListenerForDepMgmt methods -----------------------------------
    
    /**
     * {@inheritDoc}
     */
    public void manageArtifactVersion( Artifact artifact, Artifact replacement )
    {
        log( "manageArtifactVersion: artifact=" + artifact + ", replacement=" + replacement );
        
        /*
         * DefaultArtifactCollector calls manageArtifact twice: first with the change; then subsequently with no change.
         * We ignore the second call when the versions are equal.
         */
        if ( isCurrentNodeIncluded() && !replacement.getVersion().equals( artifact.getVersion() ) )
        {
            /*
             * Cache management information and apply in includeArtifact, since DefaultArtifactCollector mutates the
             * artifact and then calls includeArtifact after manageArtifact.
             */
            managedVersions.put( replacement.getId(), artifact.getVersion() );
        }
    }

    /**
     * {@inheritDoc}
     */
    public void manageArtifactScope( Artifact artifact, Artifact replacement )
    {
        log( "manageArtifactScope: artifact=" + artifact + ", replacement=" + replacement );
        
        /*
         * DefaultArtifactCollector calls manageArtifact twice: first with the change; then subsequently with no change.
         * We ignore the second call when the scopes are equal.
         */
        if ( isCurrentNodeIncluded() && !replacement.getScope().equals( artifact.getScope() ) )
        {
            /*
             * Cache management information and apply in includeArtifact, since DefaultArtifactCollector mutates the
             * artifact and then calls includeArtifact after manageArtifact.
             */
            managedScopes.put( replacement.getId(), artifact.getScope() );
        }
    }
    
    // public methods ---------------------------------------------------------

    /**
     * Gets a list of all dependency nodes in the computed dependency tree.
     * 
     * @return a list of dependency nodes
     * @deprecated As of 1.1, use a {@link CollectingDependencyNodeVisitor} on the root dependency node
     */
    public Collection getNodes()
    {
        return Collections.unmodifiableCollection( nodesByArtifact.values() );
    }

    /**
     * Gets the root dependency node of the computed dependency tree.
     * 
     * @return the root node
     */
    public DependencyNode getRootNode()
    {
        return rootNode;
    }

    // private methods --------------------------------------------------------
    
    /**
     * Writes the specified message to the log at debug level with indentation for the current node's depth.
     * 
     * @param message
     *            the message to write to the log
     */
    private void log( String message )
    {
        int depth = parentNodes.size();

        StringBuffer buffer = new StringBuffer();

        for ( int i = 0; i < depth; i++ )
        {
            buffer.append( "  " );
        }

        buffer.append( message );

        logger.debug( buffer.toString() );
    }

    /**
     * Creates a new dependency node for the specified artifact and appends it to the current parent dependency node.
     * 
     * @param artifact
     *            the attached artifact for the new dependency node
     * @return the new dependency node
     */
    private DependencyNode createNode( Artifact artifact )
    {
        DependencyNode node = new DependencyNode( artifact );

        if ( !parentNodes.isEmpty() )
        {
            DependencyNode parent = (DependencyNode) parentNodes.peek();

            parent.addChild( node );
        }

        return node;
    }
    
    /**
     * Creates a new dependency node for the specified artifact, appends it to the current parent dependency node and
     * puts it into the dependency node cache.
     * 
     * @param artifact
     *            the attached artifact for the new dependency node
     * @return the new dependency node
     */
    // package protected for unit test
    DependencyNode addNode( Artifact artifact )
    {
        DependencyNode node = createNode( artifact );

        DependencyNode previousNode = (DependencyNode) nodesByArtifact.put( node.getArtifact(), node );
        
        if ( previousNode != null )
        {
            throw new IllegalStateException( "Duplicate node registered for artifact: " + node.getArtifact() );
        }
        
        if ( rootNode == null )
        {
            rootNode = node;
        }

        currentNode = node;
        
        return node;
    }

    /**
     * Gets the dependency node for the specified artifact from the dependency node cache.
     * 
     * @param artifact
     *            the artifact to find the dependency node for
     * @return the dependency node, or <code>null</code> if the specified artifact has no corresponding dependency
     *         node
     */
    private DependencyNode getNode( Artifact artifact )
    {
        return (DependencyNode) nodesByArtifact.get( artifact );
    }

    /**
     * Removes the dependency node for the specified artifact from the dependency node cache.
     * 
     * @param artifact
     *            the artifact to remove the dependency node for
     */
    private void removeNode( Artifact artifact )
    {
        DependencyNode node = (DependencyNode) nodesByArtifact.remove( artifact );

        if ( !artifact.equals( node.getArtifact() ) )
        {
            throw new IllegalStateException( "Removed dependency node artifact was expected to be " + artifact
                            + " but was " + node.getArtifact() );
        }
    }

    /**
     * Gets whether the all the ancestors of the dependency node currently being processed by this listener have an
     * included state.
     * 
     * @return <code>true</code> if all the ancestors of the current dependency node have a state of
     *         <code>INCLUDED</code>
     */
    private boolean isCurrentNodeIncluded()
    {
        boolean included = true;

        for ( Iterator iterator = parentNodes.iterator(); included && iterator.hasNext(); )
        {
            DependencyNode node = (DependencyNode) iterator.next();

            if ( node.getState() != DependencyNode.INCLUDED )
            {
                included = false;
            }
        }

        return included;
    }

    /**
     * Updates the specified node with any dependency management information cached in prior <code>manageArtifact</code>
     * calls.
     * 
     * @param node
     *            the node to update
     */
    private void flushDependencyManagement( DependencyNode node )
    {
        Artifact artifact = node.getArtifact();
        String premanagedVersion = (String) managedVersions.get( artifact.getId() );
        String premanagedScope = (String) managedScopes.get( artifact.getId() );
        
        if ( premanagedVersion != null || premanagedScope != null )
        {
            if ( premanagedVersion != null )
            {
                node.setPremanagedVersion( premanagedVersion );
            }
            
            if ( premanagedScope != null )
            {
                node.setPremanagedScope( premanagedScope );
            }
            
            premanagedVersion = null;
            premanagedScope = null;
        }
    }
}
