package org.apache.ant.antunit;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;

/** 
 * Run antunit tests suites.  This AntUnitScriptRunner is responsible for the 
 * management of the ant project and the correct invocation the target (taking 
 * into account properly the [case]setUp and [case]tearDown targets).
 * The user can however provide the order of the test targets and or can filter
 * the list of test targets to execute.
 * The user must also provide its ProjectFactory and an AntUnitExecutionNotifier.
 * @since 1.2 
 */
public class AntUnitScriptRunner {

    /**
     * name of the magic setUp target.
     */
    private static final String SETUP = "setUp";

    /**
     * prefix that identifies test targets.
     */
    private static final String TEST = "test";

    /**
     * name of the magic tearDown target.
     */
    private static final String TEARDOWN = "tearDown";

    /**
     * name of the magic suiteSetUp target.
     */
    private static final String SUITESETUP = "suiteSetUp";

    /**
     * name of the magic suiteTearDown target.
     */
    private static final String SUITETEARDOWN = "suiteTearDown";

    /**
     * Object used to create projects in order to support test isolation.
     */
    private final ProjectFactory prjFactory;
    
    /**
     * Indicates if the startSuite method has been invoked.  Use to fail fast if the
     * the caller forget to call the startSuite method
     */
    private boolean isSuiteStarted;
    
    /**
     * Does that script have a setUp target (defined when scanning the script)
     */
    private final boolean hasSetUp;

    /**
     * Does that script have a tearDown target (defined when scanning the script)
     */
    private final boolean hasTearDown;

    /**
     * Does that script has a suiteSetUp target.
     */
    private final boolean hasSuiteSetUp;

    /**
     * Does that script has a suite tearDown target that should be executed.
     */
    private final boolean hasSuiteTearDown;

    /**
     * List of target names
     */
    private final List testTargets;

    /** 
     * The project currently used.
     */
    private Project project = null;

    /** 
     * Indicates if a target has already be executed using this project. 
     * Value is undefined when project is null.
     */
    private boolean projectIsDirty;

    
    /**
     * Create a new AntScriptRunner on the given environment.
     * @param prjFactory A factory for the ant project that will contains the antunit test to execute.
     * The factory might be invoked multiple time in order to provide test isolation.
     */
    public AntUnitScriptRunner(ProjectFactory prjFactory) {
        this.prjFactory = prjFactory;
        Project newProject = getCurrentProject();
        Map targets = newProject.getTargets();
        hasSetUp = targets.containsKey(SETUP);
        hasTearDown = targets.containsKey(TEARDOWN);
        hasSuiteSetUp = targets.containsKey(SUITESETUP);
        hasSuiteTearDown = targets.containsKey(SUITETEARDOWN);
        testTargets = new LinkedList();
        Iterator it = targets.keySet().iterator();
        while (it.hasNext()) {
            String name = (String) it.next();
            if (name.startsWith(TEST) && !name.equals(TEST)) {
                testTargets.add(name);
            }
        }
    }

    /**
     * Get the project currently in use.  The caller is not allowed to invoke a target or
     * do anything that would break the isolation of the test targets.
     */
    public final Project getCurrentProject() {
    	//Method is final because it is called from the constructor
        if (project == null) {
            project = prjFactory.createProject();
            projectIsDirty = false;
        }
        return project;
    }

    /**
     * Get a project that has not yet been used in order to execute a target on it.
     */
    private Project getCleanProject() {
        if (project == null || projectIsDirty) {
            project = prjFactory.createProject();
        }
        //we already set isDirty to true in order to make sure we didn't reuse
        //this project next time getCleanProject is called.  
        projectIsDirty = true;
        return project;
    }

    /**
     * @return List<String> List of test targets of the script file
     */
    public List getTestTartgets() {
        return testTargets;
    }

    /**
     * Provides the name of the active script.
     */
    public String getName() {
        return getCurrentProject().getName();
    }

    /**
     * Executes the suiteSetUp target if presents and report any execution error.
     * A failure is reported to the notifier and by returning false.
     * Note that if the method return false, you are not allowed to run targets.
     * @return false in case of execution failure.  true in case of success. 
     */
    private boolean startSuite(AntUnitExecutionNotifier notifier) {
        getCurrentProject().fireBuildStarted();
        if (hasSuiteSetUp) {
            try {
                Project newProject = getCleanProject();
                newProject.executeTarget(SUITESETUP);
            } catch (BuildException e) {
                notifier.fireStartTest(SUITESETUP);
                fireFailOrError(SUITESETUP, e, notifier);
                return false;
            }
        }
        isSuiteStarted = true; //set to true only if suiteSetUp executed properly.
        return true;
    }

    /** 
     * Run the specific test target, possibly between the setUp and tearDown targets if
     * it exists.  Exception or failures are reported to the notifier.
     * @param name name of the test target to execute.
     * @param notifier will receive execution notifications.
     * @pre startSuite has been invoked successfully
     */
    private void runTarget(String name, AntUnitExecutionNotifier notifier) {
        if (!isSuiteStarted) {
            throw new AssertionError();
        }
        Project newProject = getCleanProject();
        Vector v = new Vector();
        if (hasSetUp) {
            v.add(SETUP);
        }
        v.add(name);
        // create and register a logcapturer on the newProject
        LogCapturer lc = new LogCapturer(newProject);
        try {
            notifier.fireStartTest(name);
            newProject.executeTargets(v);
        } catch (BuildException e) {
            fireFailOrError(name, e, notifier);
        } finally {
            // fire endTest here instead of the endTarget
            // event, otherwise an error would be
            // registered after the endTest event -
            // endTarget is called before this method's catch block
            // is reached.
            notifier.fireEndTest(name);
            // clean up
            if (hasTearDown) {
                try {
                    newProject.executeTarget(TEARDOWN);
                } catch (final BuildException e) {
                    fireFailOrError(name, e, notifier);
                }
            }
        }
    }

    /**
     * Executes the suiteTearDown target if presents and report any execution error.
     * @param caught Any internal exception triggered (and caught) by the caller indicating that 
     * the execution could not be invoked as expected.  
     * @param notifier will receive execution notifications.
     */
    private void endSuite(Throwable caught, AntUnitExecutionNotifier notifier) {
        if (hasSuiteTearDown) {
            try {
                Project newProject = getCleanProject();
                newProject.executeTarget(SUITETEARDOWN);
            } catch (BuildException e) {
                notifier.fireStartTest(SUITETEARDOWN);
                fireFailOrError(SUITETEARDOWN, e, notifier);
            }
        }
        getCurrentProject().fireBuildFinished(caught);
        isSuiteStarted = false;
    }

    /**
     * Try to see whether the BuildException e is an AssertionFailedException
     * or is caused by an AssertionFailedException. If so, fire a failure for 
     * given targetName.  Otherwise fire an error.
     */
    private void fireFailOrError(String targetName, BuildException e, 
                                 AntUnitExecutionNotifier notifier) {
        boolean failed = false;
        Throwable t = e;
        while (t != null && t instanceof BuildException) {
            if (t instanceof AssertionFailedException) {
                failed = true;
                notifier.fireFail(targetName, (AssertionFailedException) t);
                break;
            }
            t = ((BuildException) t).getCause();
        }

        if (!failed) {
            notifier.fireError(targetName, e);
        }
    }


    /**
     * Executes the suite.
     * @param suiteTargets An ordered list of test targets.  It must be a sublist of getTestTargets
     * @param notifier 
     */
    public void runSuite(List suiteTargets, AntUnitExecutionNotifier notifier) {
        Throwable caught = null;
        try {
            if (!startSuite(notifier)) {
                return;
            }
            Iterator iter = suiteTargets.iterator();
            while (iter.hasNext()) {
                String name = (String) iter.next();
                runTarget(name, notifier);
            }
        } catch (Throwable e) {
            caught = e;
        } finally {
            endSuite(caught, notifier);
        }
    }

}