/*
 * 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 org.apache.ant.antunit.junit3;

import java.io.File;
import java.io.PrintStream;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestResult;
import junit.framework.TestSuite;

import org.apache.ant.antunit.AntUnitExecutionNotifier;
import org.apache.ant.antunit.AntUnitScriptRunner;
import org.apache.ant.antunit.ProjectFactory;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.MagicNames;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;

/**
 * A JUnit 3 TestSuite that group a suite of AntUnit targets coming from an ant
 * script.
 */
public class AntUnitSuite extends TestSuite {

    private final AntUnitScriptRunner antScriptRunner;
    private final MultiProjectDemuxOutputStream stderr;
    private final MultiProjectDemuxOutputStream stdout;
    private final Test initializationReportingTest;

    /**
     * Create a JUnit TestSuite that when executed will run the given ant
     * script.<br/> 
     * Note that it is the responsibility of the caller to give the correct
     * File reference. Namely, if the File is a relative file, it will
     * be resolve relatively to the execution directory (which might be
     * different different from the project root directory).
     * 
     * @param scriptFile
     *            AntUnit script file
     * @param rootClass
     *            The test class that creates this suite. This is used to give
     *            a name to the suite so that an IDE can reexecute this suite.
     */
    public AntUnitSuite(File scriptFile, Class rootClass) {
        AntUnitScriptRunner createdScriptRunner = null;
        try {
            MyProjectFactory prjFactory = new MyProjectFactory(scriptFile);
            createdScriptRunner = new AntUnitScriptRunner(prjFactory);
        } catch (BuildException e) {
            antScriptRunner = null;
            stdout = null;
            stderr = null;
            initializationReportingTest = error(e);
            addTest(initializationReportingTest);
            return;
        }
        antScriptRunner = createdScriptRunner;
        initializationReportingTest = null;
        stdout = new MultiProjectDemuxOutputStream(antScriptRunner, false);
        stderr = new MultiProjectDemuxOutputStream(antScriptRunner, true);
        setName(antScriptRunner.getName() + "[" + scriptFile + "]");        
        setName(rootClass.getName());// Allows eclipse to reexecute the test
        List testTargets = antScriptRunner.getTestTartgets();
        for (Iterator it = testTargets.iterator(); it.hasNext();) {
            String target = (String) it.next();
            AntUnitTestCase tc = new AntUnitTestCase(this, scriptFile, target);
            addTest(tc);
        }
    }

    /**
     * Constructor used by AntUnitTestCase when a single test case is created.
     * The difference with the public constructor is this version doesn't set
     * the name.
     * @throws BuildException when the file project can not be create (parsed/read)
     */
    AntUnitSuite(AntUnitTestCase singleTc , File scriptFile) throws BuildException {
        MyProjectFactory prjFactory = new MyProjectFactory(scriptFile);
        antScriptRunner = new AntUnitScriptRunner(prjFactory);
        //the exception is throwed, and it is up to the AntUnitTestCase to handle it.
        initializationReportingTest = null; 
        stdout = new MultiProjectDemuxOutputStream(antScriptRunner, false);
        stderr = new MultiProjectDemuxOutputStream(antScriptRunner, true);
        setName(antScriptRunner.getName() + "[" + scriptFile + "]");
        addTest(singleTc);
    }
    
    /**
     * @Override Run the full AntUnit suite
     */
    public void run(TestResult testResult) {
        if (initializationReportingTest!=null) {
            initializationReportingTest.run(testResult);
        } else {
            List testTartgets = antScriptRunner.getTestTartgets();
            JUnitNotificationAdapter notifier = new JUnitNotificationAdapter(
                    testResult, tests());
            runInContainer(testTartgets, notifier);
        }
    }

    
    private static Test error(final BuildException ex) {
        return new TestCase("warning") {
            protected void runTest() throws BuildException {
                throw ex;
            }
        };
    }


    
    /**
     * @Override Run a single test target of the AntUnit suite. suiteSetUp,
     *           setUp, tearDown and suiteTearDown are executed around it.
     */
    public void runTest(Test test, TestResult result) {
        if (initializationReportingTest!=null) {
            initializationReportingTest.run(result);
        } else {
            String targetName = ((AntUnitTestCase) test).getTarget();
            List singleTargetList = Collections.singletonList(targetName);
            JUnitNotificationAdapter notifier = new JUnitNotificationAdapter(
                    result, tests());
            runInContainer(singleTargetList, notifier);
        }
    }

    /**
     * Execute the test suite in a 'container' similar to the ant 'container'.
     * When ant executes a project it redirect the input and the output. In this
     * context we will only redirect output (unit test are not supposed to be
     * interactive).<br/>
     * 
     * @param targetList
     *            The list of test target to execute
     * @param notifier
     *            The AntUnit notifier that will receive execution notifications
     */
    public void runInContainer(List targetList, AntUnitExecutionNotifier notifier) {        
        PrintStream savedErr = System.err;
        PrintStream savedOut = System.out;
        try {
            System.setOut(new PrintStream(stdout));
            System.setErr(new PrintStream(stderr));
            antScriptRunner.runSuite(targetList, notifier);
        } finally {
            System.setOut(savedOut);
            System.setErr(savedErr);
        }
    }

    /**
     * The antscript project factory that creates projects in a junit context.
     */
    private static class MyProjectFactory implements ProjectFactory {

        private final File scriptFile;
        private final PrintStream realStdErr = System.err;
        private final PrintStream realStdOut = System.out;

        public MyProjectFactory(File scriptFile) {
            this.scriptFile = scriptFile;
        }

        public Project createProject() { 
            ProjectHelper prjHelper = ProjectHelper.getProjectHelper();
            Project prj = new Project();
            DefaultLogger logger = new DefaultLogger();
            logger.setMessageOutputLevel(Project.MSG_INFO);
            logger.setErrorPrintStream(realStdErr);
            logger.setOutputPrintStream(realStdOut);
            prj.addBuildListener(logger);
            String absolutePath = scriptFile.getAbsolutePath();
            prj.setUserProperty(MagicNames.ANT_FILE, absolutePath);
            prj.addReference(ProjectHelper.PROJECTHELPER_REFERENCE, prjHelper);
            prj.init();
            prjHelper.parse(prj, scriptFile);
            return prj;
        }
    }

}
