package org.eclipse.aether.util.graph.visitor;

/*
 * 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.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.graph.DependencyVisitor;

import java.io.File;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Abstract base class for depth first dependency tree traversers. Subclasses of this visitor will visit each node
 * exactly once regardless how many paths within the dependency graph lead to the node such that the resulting node
 * sequence is free of duplicates.
 * <p>
 * Actual vertex ordering (preorder, inorder, postorder) needs to be defined by subclasses through appropriate
 * implementations for {@link #visitEnter(org.eclipse.aether.graph.DependencyNode)} and
 * {@link #visitLeave(org.eclipse.aether.graph.DependencyNode)}
 */
abstract class AbstractDepthFirstNodeListGenerator
    implements DependencyVisitor
{

    private final Map<DependencyNode, Object> visitedNodes;

    protected final List<DependencyNode> nodes;

    AbstractDepthFirstNodeListGenerator()
    {
        nodes = new ArrayList<DependencyNode>( 128 );
        visitedNodes = new IdentityHashMap<DependencyNode, Object>( 512 );
    }

    /**
     * Gets the list of dependency nodes that was generated during the graph traversal.
     * 
     * @return The list of dependency nodes, never {@code null}.
     */
    public List<DependencyNode> getNodes()
    {
        return nodes;
    }

    /**
     * Gets the dependencies seen during the graph traversal.
     * 
     * @param includeUnresolved Whether unresolved dependencies shall be included in the result or not.
     * @return The list of dependencies, never {@code null}.
     */
    public List<Dependency> getDependencies( boolean includeUnresolved )
    {
        List<Dependency> dependencies = new ArrayList<Dependency>( getNodes().size() );

        for ( DependencyNode node : getNodes() )
        {
            Dependency dependency = node.getDependency();
            if ( dependency != null )
            {
                if ( includeUnresolved || dependency.getArtifact().getFile() != null )
                {
                    dependencies.add( dependency );
                }
            }
        }

        return dependencies;
    }

    /**
     * Gets the artifacts associated with the list of dependency nodes generated during the graph traversal.
     * 
     * @param includeUnresolved Whether unresolved artifacts shall be included in the result or not.
     * @return The list of artifacts, never {@code null}.
     */
    public List<Artifact> getArtifacts( boolean includeUnresolved )
    {
        List<Artifact> artifacts = new ArrayList<Artifact>( getNodes().size() );

        for ( DependencyNode node : getNodes() )
        {
            if ( node.getDependency() != null )
            {
                Artifact artifact = node.getDependency().getArtifact();
                if ( includeUnresolved || artifact.getFile() != null )
                {
                    artifacts.add( artifact );
                }
            }
        }

        return artifacts;
    }

    /**
     * Gets the files of resolved artifacts seen during the graph traversal.
     * 
     * @return The list of artifact files, never {@code null}.
     */
    public List<File> getFiles()
    {
        List<File> files = new ArrayList<File>( getNodes().size() );

        for ( DependencyNode node : getNodes() )
        {
            if ( node.getDependency() != null )
            {
                File file = node.getDependency().getArtifact().getFile();
                if ( file != null )
                {
                    files.add( file );
                }
            }
        }

        return files;
    }

    /**
     * Gets a class path by concatenating the artifact files of the visited dependency nodes. Nodes with unresolved
     * artifacts are automatically skipped.
     * 
     * @return The class path, using the platform-specific path separator, never {@code null}.
     */
    public String getClassPath()
    {
        StringBuilder buffer = new StringBuilder( 1024 );

        for ( Iterator<DependencyNode> it = getNodes().iterator(); it.hasNext(); )
        {
            DependencyNode node = it.next();
            if ( node.getDependency() != null )
            {
                Artifact artifact = node.getDependency().getArtifact();
                if ( artifact.getFile() != null )
                {
                    buffer.append( artifact.getFile().getAbsolutePath() );
                    if ( it.hasNext() )
                    {
                        buffer.append( File.pathSeparatorChar );
                    }
                }
            }
        }

        return buffer.toString();
    }

    /**
     * Marks the specified node as being visited and determines whether the node has been visited before.
     * 
     * @param node The node being visited, must not be {@code null}.
     * @return {@code true} if the node has not been visited before, {@code false} if the node was already visited.
     */
    protected boolean setVisited( DependencyNode node )
    {
        return visitedNodes.put( node, Boolean.TRUE ) == null;
    }

    public abstract boolean visitEnter( DependencyNode node );

    public abstract boolean visitLeave( DependencyNode node );

}
