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.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;

/**
 * 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 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;
    
    /**
     * The id of the currently managed artifact, or <code>null</code> if the current artifact is not managed.
     */
    private String managedId;
    
    /**
     * The original version of the currently managed artifact, or <code>null</code> if the current artifact is not
     * managed.
     */
    private String premanagedVersion;
    
    /**
     * The original scope of the currently managed artifact, or <code>null</code> if the current artifact is not
     * managed.
     */
    private String premanagedScope;

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

    /**
     * Creates a new dependency tree resolution listener.
     */
    public DependencyTreeResolutionListener()
    {
        parentNodes = new Stack();
        nodesByArtifact = new IdentityHashMap();
        rootNode = null;
        currentNode = null;
        managedId = null;
        premanagedVersion = null;
        premanagedScope = null;
    }

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

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#testArtifact(org.apache.maven.artifact.Artifact)
     */
    public void testArtifact( Artifact artifact )
    {
        // no-op
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#startProcessChildren(org.apache.maven.artifact.Artifact)
     */
    public void startProcessChildren( Artifact artifact )
    {
        if ( !currentNode.getArtifact().equals( artifact ) )
        {
            throw new IllegalStateException( "Artifact was expected to be " + currentNode.getArtifact() + " but was "
                            + artifact );
        }

        parentNodes.push( currentNode );
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#endProcessChildren(org.apache.maven.artifact.Artifact)
     */
    public void endProcessChildren( Artifact artifact )
    {
        DependencyNode node = (DependencyNode) parentNodes.pop();

        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 );
        }
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#includeArtifact(org.apache.maven.artifact.Artifact)
     */
    public void 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.
             */
            if ( premanagedVersion != null || premanagedScope != null )
            {
                if ( !managedId.equals( artifact.getId() ) )
                {
                    throw new IllegalStateException( "Managed artifact id was expected to be " + managedId + " but was " + artifact.getId() );
                }
                
                if ( premanagedVersion != null )
                {
                    node.setPremanagedVersion( premanagedVersion );
                }
                
                if ( premanagedScope != null )
                {
                    node.setPremanagedScope( premanagedScope );
                }
                
                managedId = null;
                premanagedVersion = null;
                premanagedScope = null;
            }
        }
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#omitForNearer(org.apache.maven.artifact.Artifact,
     *      org.apache.maven.artifact.Artifact)
     */
    public void omitForNearer( Artifact omitted, Artifact 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 );
            
            
            
            DependencyNode keptNode = getNode( kept );
            
            if ( keptNode == null )
            {
                addNode( kept );
            }
        }
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#updateScope(org.apache.maven.artifact.Artifact,
     *      java.lang.String)
     */
    public void updateScope( Artifact artifact, String scope )
    {
        DependencyNode node = getNode( artifact );

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

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

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#manageArtifact(org.apache.maven.artifact.Artifact,
     *      org.apache.maven.artifact.Artifact)
     */
    public void manageArtifact( Artifact artifact, Artifact replacement )
    {
        // TODO: remove when ResolutionListenerForDepMgmt merged into ResolutionListener
        
        if ( replacement.getVersion() != null )
        {
            manageArtifactVersion( artifact, replacement );
        }
        
        if ( replacement.getScope() != null )
        {
            manageArtifactScope( artifact, replacement );
        }
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#omitForCycle(org.apache.maven.artifact.Artifact)
     */
    public void omitForCycle( Artifact artifact )
    {
        if ( isCurrentNodeIncluded() )
        {
            DependencyNode node = createNode( artifact );

            node.omitForCycle();
        }
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#updateScopeCurrentPom(org.apache.maven.artifact.Artifact,
     *      java.lang.String)
     */
    public void updateScopeCurrentPom( Artifact artifact, String 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 );
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#selectVersionFromRange(org.apache.maven.artifact.Artifact)
     */
    public void selectVersionFromRange( Artifact artifact )
    {
        // TODO: track version selection from range in node (MNG-3093)
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListener#restrictRange(org.apache.maven.artifact.Artifact,
     *      org.apache.maven.artifact.Artifact, org.apache.maven.artifact.versioning.VersionRange)
     */
    public void restrictRange( Artifact artifact, Artifact artifact1, VersionRange versionRange )
    {
        // TODO: track range restriction in node (MNG-3093)
    }
    
    // ResolutionListenerForDepMgmt methods -----------------------------------
    
    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListenerForDepMgmt#manageArtifactVersion(org.apache.maven.artifact.Artifact,
     *      org.apache.maven.artifact.Artifact)
     */
    public void manageArtifactVersion( Artifact artifact, Artifact 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.
             */
            managedId = replacement.getId();
            premanagedVersion = artifact.getVersion();
        }
    }

    /*
     * @see org.apache.maven.artifact.resolver.ResolutionListenerForDepMgmt#manageArtifactScope(org.apache.maven.artifact.Artifact,
     *      org.apache.maven.artifact.Artifact)
     */
    public void manageArtifactScope( Artifact artifact, Artifact 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.
             */
            managedId = replacement.getId();
            premanagedScope = artifact.getScope();
        }
    }

    /**
     * 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 --------------------------------------------------------

    /**
     * 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
     */
    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;
    }
}
