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

package flex2.tools.oem;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import flex2.compiler.util.graph.Algorithms;
import flex2.compiler.util.graph.DependencyGraph;
import flex2.compiler.util.graph.Vertex;
import flex2.compiler.util.graph.Visitor;

/**
 * The <code>Project</code> class groups a number of <code>Builder</code> instances. For example, <code>Application</code>
 * and <code>Library</code>. These <code>Builder</code> instances
 * can be unrelated, or they can depend on each other. If they depend on each other, this class
 * provides dependency analysis and recommends build order.
 *
 * The <code>addBuilder()</code> method adds <code>Application</code> and <code>Library</code> instances
 * to the <code>Project</code>; for example:
 * 
 * <pre>
 * Library lib = new Library();
 * lib.setOutput(new File("foo.swc"));
 * 
 * Application app = new Application(new File("MyApp.mxml"));
 * app.setOutput(new File("MyApp.swf"));
 * 
 * p.addBuilder(lib);
 * p.addBuilder(app);
 * </pre>
 * 
 * To ensure that the <code>Application</code> uses the SWC archive that was built by the <code>Library</code>,
 * you can set the dependency by using the <code>dependsOn()</code> method; for example:
 * 
 * <pre>
 * p.dependsOn(app, lib);
 * </pre>
 * 
 * If all the <code>Builder</code> instances have pre-defined output destinations (for example, the 
 * <code>setOutput(File)</code> method was called), the <code>build(boolean)</code> method determines
 * the build order and builds the SWF and SWC files; for example:
 * 
 * <pre>
 * p.build(true);
 * </pre>
 * 
 * If you want the <code>Project</code> to provide the build order and you want to run the
 * build separately, use the <code>getBuildOrder()</code> method; for example:
 * 
 * <pre>
 * for (Iterator i = p.getBuildOrder(); i.hasNext(); )
 * {
 *     Object obj = i.next();
 *     if (obj instanceof Application)
 *     {
 *         Application app = (Application) obj;
 *         //...
 *     }
 *     else if (obj instanceof Library)
 *     {
 *         Library lib = (Library) obj;
 *         //...
 *     }
 * }
 * </pre>
 * 
 * @see flex2.tools.oem.Application
 * @see flex2.tools.oem.Library
 * @version 2.0.1
 */
public class Project
{
    /**
     * Constructor.
     */
    public Project()
    {
        dependencies = new DependencyGraph<Builder>();
    }
    
    private DependencyGraph<Builder> dependencies;
    
    /**
     * Adds an <code>Application</code> or a <code>Library</code> to the <code>Project</code>.
     * 
     * @param builder An instance of the <code>Application</code> or a <code>Library</code> class.
     */
    public void addBuilder(Builder builder)
    {
        String name = Integer.toString(builder.hashCode());
        dependencies.put(name, builder);
        
        if (!dependencies.containsVertex(name))
        {
            dependencies.addVertex(new Vertex<String,Builder>(name));
        }
    }
    
    /**
     * Removes an <code>Application</code> or a <code>Library</code> from the <code>Project</code>.
     * 
     * @param builder An instance of the <code>Application</code> or a <code>Library</code> class.
     */
    public void removeBuilder(Builder builder)
    {
        String name = Integer.toString(builder.hashCode());
        dependencies.remove(name);
        dependencies.removeVertex(name);
    }
    
    /**
     * Instructs the <code>Project</code> that one <code>Builder</code> depends on the other.
     * Both <code>Builder</code> instances must first be added to this <code>Project</code>.
     * 
     * <p>
     * <code>builder1</code> depends on <code>builder2</code>.
     * 
     * @param builder1 A <code>Builder</code>. This <code>Builder</code> depends on the other.
     * @param builder2 A <code>Builder</code>.
     */
    public void dependsOn(Builder builder1, Builder builder2)
    {
        String head = Integer.toString(builder1.hashCode()), tail = Integer.toString(builder2.hashCode());
        if (!head.equals(tail) && dependencies.containsKey(head) && dependencies.containsKey(tail) &&
            !dependencies.dependencyExists(head, tail))
        {
            dependencies.addDependency(head, tail);
        }
    }

    /**
     * Gets the build order for the <code>Project</code>. The build order is determined by the dependencies among
     * <code>Builder</code> instances.
     * 
     * @return <code>Iterator</code> build order; the elements are either instance of the <code>Application</code> 
     * class or the <code>Library</code> class.
     */
    public Iterator<Builder> getBuildOrder()
    {
        final List<Builder> buildOrder = new ArrayList<Builder>(dependencies.size());
        
        Algorithms.topologicalSort(dependencies, new Visitor<Vertex<String,Builder>>()
        {   
            public void visit(Vertex<String,Builder> v)
            {
                String name = v.getWeight();
                buildOrder.add(dependencies.get(name));
            }
        });
        
        return buildOrder.iterator();
    }
    
    /**
     * Detects cyclical dependencies in this <code>Project</code>. This method returns the <code>Builder</code>
     * instances that are in cyclical dependencies. If there are no cyclical dependencies, this method 
     * returns <code>null</code>. 
     * 
     * <p>
     * The <code>Builder</code> instances in cyclical dependencies do not participate in
     * <code>build(boolean)</code>, <code>clean()</code> or <code>stop()</code> methods.
     * 
     * <p>
     * The <code>getBuildOrder()</code> method does not iterate over <code>Builder</code> instances that are in cyclical dependencies.
     * 
     * <p>
     * You should call this method at least once.
     * 
     * @return A set of <code>Builder</code> instances that are in cyclical dependencies.
     */
    public Set detectCycles()
    {
        Set builders = Algorithms.detectCycles(dependencies);
        if (builders != null && builders.size() == 0)
        {
            builders = null;
        }
        return builders;
    }
    
    /**
     * Builds the <code>Project</code>. If the input argument is <code>false</code>, the <code>build(boolean)</code> 
     * method rebuilds the <code>Project</code>. If the input argument is <code>true</code>, this method builds incrementally.
     * 
     * <p>
     * All the <code>Application</code> and <code>Library</code> objects
     * have their output destinations set with the <code>Application.setOutput()</code> and
     * <code>Library.setOutput/setDirectory()</code> methods.
     * 
     * @param incremental If <code>true</code>, build incrementally; if <code>false</code>, rebuild.
     * 
     * @throws IOException when an I/O error occurs in any one of the compilations.
     */
    public void build(boolean incremental) throws IOException
    {
        for (Iterator<Builder> i = getBuildOrder(); i.hasNext(); )
        {           
            Builder builder = i.next();
            if (builder != null)
            {
                builder.build(incremental);
            }
        }
    }
    
    /**
     * Deletes the <code>Application</code> and <code>Library</code> files in the <code>Project</code>.
     * <p>
     * The <code>clean()</code> method does not remove compiler options or reset the output location.
     */
    public void clean()
    {
        for (Iterator<Builder> i = getBuildOrder(); i.hasNext(); )
        {           
            Builder builder = i.next();
            if (builder != null)
            {
                builder.clean();
            }
        }
    }
    
    /**
     * Stops the <code>Project</code>. This method calls the <code>Application.stop()</code> and <code>Library.stop()</code> method
     * for each <code>Application</code> and <code>Library</code> in the <code>Project</code>.
     */
    public void stop()
    {
        for (Iterator<Builder> i = getBuildOrder(); i.hasNext(); )
        {           
            Builder builder = i.next();
            if (builder != null)
            {
                builder.stop();
            }
        }
    }
}

