/* ==========================================================================
 * Copyright 2008 mkleint
 *
 * Licensed 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.
 * =========================================================================
 */
package org.codehaus.mojo.nbm;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.shared.dependency.graph.DependencyNode;
import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
import org.codehaus.mojo.nbm.utils.ExamineManifest;

/**
 * A dependency node visitor that collects visited nodes that are known libraries or are
 * children of known libraries
 * @author milos kleint
 */
public class CollectModuleLibrariesNodeVisitor
    implements DependencyNodeVisitor
{

    /**
     * The collected list of nodes.
     */
    private final Map<String, List<Artifact>> directNodes;

    private final Map<String, List<Artifact>> transitiveNodes;

    private Map<String, Artifact> artifacts;

    private Map<Artifact, ExamineManifest> examinerCache;

    private final Log log;

    private MojoExecutionException throwable;

    private DependencyNode root;

    private Stack<String> currentModule = new Stack<String>();
    private static final String LIB_ID = "!@#$%^&ROOT";

    private final boolean useOSGiDependencies;

    /**
     * Creates a dependency node visitor that collects visited nodes for further processing.
     * @param runtimeArtifacts list of runtime artifacts
     * @param examinerCache cache of netbeans manifest for artifacts
     * @param log mojo logger
     * @param root dependency to start collect with
     * @param useOSGiDependencies whether to allow osgi dependencies or not
     */
    public CollectModuleLibrariesNodeVisitor(
        List<Artifact> runtimeArtifacts, Map<Artifact, ExamineManifest> examinerCache,
        Log log, DependencyNode root, boolean useOSGiDependencies )
    {
        directNodes = new HashMap<String, List<Artifact>>();
        transitiveNodes = new HashMap<String, List<Artifact>>();
        artifacts = new HashMap<String, Artifact>();
        for ( Artifact a : runtimeArtifacts )
        {
            artifacts.put( a.getDependencyConflictId(), a );
        }
        this.examinerCache = examinerCache;
        this.log = log;
        this.root = root;
        this.useOSGiDependencies = useOSGiDependencies;
    }

    /**
     * {@inheritDoc}
     */
    public boolean visit( DependencyNode node )
    {
        if ( throwable != null )
        {
            return false;
        }
        if ( root == node )
        {
            return true;
        }
        try
        {
            Artifact artifact = node.getArtifact();
            if ( !artifacts.containsKey( artifact.getDependencyConflictId() ) )
            {
                //ignore non-runtime stuff..
                return false;
            }
            // somehow the transitive artifacts in the  tree are not always resolved?
            artifact = artifacts.get( artifact.getDependencyConflictId() );

            ExamineManifest depExaminator = examinerCache.get( artifact );
            if ( depExaminator == null )
            {
                depExaminator = new ExamineManifest( log );
                depExaminator.setArtifactFile( artifact.getFile() );
                depExaminator.checkFile();
                examinerCache.put( artifact, depExaminator );
            }
            if ( depExaminator.isNetBeansModule() || ( useOSGiDependencies && depExaminator.isOsgiBundle() ) )
            {
                currentModule.push( artifact.getDependencyConflictId() );
                ArrayList<Artifact> arts = new ArrayList<Artifact>();
                arts.add( artifact );
                if ( currentModule.size() == 1 )
                {
                    directNodes.put( currentModule.peek(), arts );
                }
                else
                {
                    transitiveNodes.put( currentModule.peek(), arts );
                }
                return true;
            }
            if ( currentModule.size() > 0 )
            {
                ////MNBMODULE-95 we are only interested in the module owned libraries
                if ( !currentModule.peek().startsWith( LIB_ID ) &&
                        AbstractNbmMojo.matchesLibrary( artifact, Collections.<String>emptyList(), depExaminator, log, useOSGiDependencies ) )
                {
                    if ( currentModule.size() == 1 )
                    {
                        directNodes.get( currentModule.peek() ).add( artifact );
                    }
                    else
                    {
                        transitiveNodes.get( currentModule.peek() ).add( artifact );
                    }
                    // if a library, iterate to it's child nodes.
                    return true;
                }
            }
            else
            {
                //MNBMODULE-95 we check the non-module dependencies to see if they
                // depend on modules/bundles. these bundles are transitive, so
                // we add the root module as the first currentModule to keep
                //any bundle/module underneath it as transitive
                currentModule.push( LIB_ID + artifact.getDependencyConflictId() );
            }
        }
        catch ( MojoExecutionException mojoExecutionException )
        {
            throwable = mojoExecutionException;
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    public boolean endVisit( DependencyNode node )
    {
        if ( throwable != null )
        {
            return false;
        }
        if ( !currentModule.empty()
            && ( currentModule.peek().equals( node.getArtifact().getDependencyConflictId() )
                            || currentModule.peek().equals( LIB_ID + node.getArtifact().getDependencyConflictId() ) ) )
        {
            currentModule.pop();
        }
        return true;
    }

    /**
     * modules declared in the project's pom
     * @return a map of module artifact lists, key is the dependencyConflictId
     * @throws MojoExecutionException if an unexpected problem occurs
     */
    public Map<String, List<Artifact>> getDeclaredArtifacts()
        throws MojoExecutionException
    {
        if ( throwable != null )
        {
            throw throwable;
        }
        return directNodes;
    }

    /**
     * modules that were picked up transitively
     * @return a map of module artifact lists, key is the dependencyConflictId
     * @throws MojoExecutionException if an unexpected problem occurs
     */
    public Map<String, List<Artifact>> getTransitiveArtifacts()
        throws MojoExecutionException
    {
        if ( throwable != null )
        {
            throw throwable;
        }
        return transitiveNodes;
    }
}
