/*******************************************************************************
 * 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.ofbiz.testtools;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestFailure;
import junit.framework.TestListener;
import junit.framework.TestResult;
import junit.framework.TestSuite;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest;
import org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter;
import org.ofbiz.base.container.Container;
import org.ofbiz.base.container.ContainerException;
import org.ofbiz.base.util.Debug;
import org.ofbiz.entity.Delegator;

/**
 * A Container implementation to run the tests configured through this testtools stuff.
 */
public class TestRunContainer implements Container {

    public static final String module = TestRunContainer.class.getName();
    public static final String logDir = "runtime/logs/test-results/";

    protected String configFile = null;
    protected String component = null;
    protected String suiteName = null;
    protected String testCase = null;
    protected String logLevel = null;

    private String name;

    @Override
    public void init(String[] args, String name, String configFile) {
        this.name = name;
        this.configFile = configFile;
        if (args != null) {
            for (String argument : args) {
                // arguments can prefix w/ a '-'. Just strip them off
                if (argument.startsWith("-")) {
                    int subIdx = 1;
                    if (argument.startsWith("--")) {
                        subIdx = 2;
                    }
                    argument = argument.substring(subIdx);
                }

                // parse the arguments
                if (argument.indexOf("=") != -1) {
                    String argumentName = argument.substring(0, argument.indexOf("="));
                    String argumentVal = argument.substring(argument.indexOf("=") + 1);

                    if ("component".equalsIgnoreCase(argumentName)) {
                        this.component = argumentVal;
                    }
                    if ("suitename".equalsIgnoreCase(argumentName)) {
                        this.suiteName = argumentVal;
                    }
                    if ("case".equalsIgnoreCase(argumentName)) {
                        this.testCase = argumentVal;
                    }
                    if ("loglevel".equalsIgnoreCase(argumentName)) {
                        this.logLevel = argumentVal;
                    }
                }
            }
        }

        // make sure the log dir exists
        File dir = new File(logDir);
        if (!dir.exists())
            dir.mkdir();
    }

    public boolean start() throws ContainerException {
        // configure log4j output logging
        if (logLevel != null) {
            int llevel = Debug.getLevelFromString(logLevel);

            for (int v = 0; v < 9; v++) {
                if (v < llevel) {
                    Debug.set(v, false);
                } else {
                    Debug.set(v, true);
                }
            }
        }

        // get the tests to run
        JunitSuiteWrapper jsWrapper = new JunitSuiteWrapper(component, suiteName, testCase);
        if (jsWrapper.getAllTestList().size() == 0) {
            throw new ContainerException("No tests found (" + component + " / " + suiteName + " / " + testCase + ")");
        }

        boolean failedRun = false;
        for (ModelTestSuite modelSuite: jsWrapper.getModelTestSuites()) {
            Delegator testDelegator = modelSuite.getDelegator();
            TestSuite suite = modelSuite.makeTestSuite();
            JUnitTest test = new JUnitTest();
            test.setName(suite.getName());

            // create the XML logger
            JunitXmlListener xml;
            try {
                xml = new JunitXmlListener(new FileOutputStream(logDir + suite.getName() + ".xml"));
            } catch (FileNotFoundException e) {
                throw new ContainerException(e);
            }

            // per-suite results
            TestResult results = new TestResult();
            results.addListener(new JunitListener());
            results.addListener(xml);

            // add the suite to the xml listener
            xml.startTestSuite(test);
            // run the tests
            suite.run(results);
            test.setCounts(results.runCount(), results.failureCount(), results.errorCount());
            // rollback all entity operations performed by the delegator
            testDelegator.rollback();
            xml.endTestSuite(test);

            if (!results.wasSuccessful()) {
                failedRun = true;
            }

            // display the results
            Debug.logInfo("[JUNIT] Results for test suite: " + suite.getName(), module);
            Debug.logInfo("[JUNIT] Pass: " + results.wasSuccessful() + " | # Tests: " + results.runCount() + " | # Failed: " +
                    results.failureCount() + " # Errors: " + results.errorCount(), module);
            if (Debug.importantOn() && !results.wasSuccessful()) {
                Debug.logInfo("[JUNIT] ----------------------------- ERRORS ----------------------------- [JUNIT]", module);
                Enumeration<?> err = results.errors();
                if (!err.hasMoreElements()) {
                    Debug.logInfo("None", module);
                } else {
                    while (err.hasMoreElements()) {
                        Object error = err.nextElement();
                        Debug.logInfo("--> " + error, module);
                        if (error instanceof TestFailure) {
                            Debug.logInfo(((TestFailure) error).trace(), module);
                        }
                    }
                }
                Debug.logInfo("[JUNIT] ------------------------------------------------------------------ [JUNIT]", module);
                Debug.logInfo("[JUNIT] ---------------------------- FAILURES ---------------------------- [JUNIT]", module);
                Enumeration<?> fail = results.failures();
                if (!fail.hasMoreElements()) {
                    Debug.logInfo("None", module);
                } else {
                    while (fail.hasMoreElements()) {
                        Object failure = fail.nextElement();
                        Debug.logInfo("--> " + failure, module);
                        if (failure instanceof TestFailure) {
                            Debug.logInfo(((TestFailure) failure).trace(), module);
                        }
                    }
                }
                Debug.logInfo("[JUNIT] ------------------------------------------------------------------ [JUNIT]", module);
            }
        }

        if (failedRun) {
            throw new ContainerException("Test run was unsuccessful");
        }
        return true;
    }

    public void stop() throws ContainerException {
    }

    public String getName() {
        return name;
    }

    class JunitXmlListener extends XMLJUnitResultFormatter {

        Map<String, Long> startTimes = new HashMap<String, Long>();

        public JunitXmlListener(OutputStream out) {
            this.setOutput(out);
        }

        @Override
        public void startTestSuite(JUnitTest suite) {
            startTimes.put(suite.getName(), System.currentTimeMillis());
            super.startTestSuite(suite);
        }

        @Override
        public void endTestSuite(JUnitTest suite) throws BuildException {
            long startTime = startTimes.get(suite.getName());
            suite.setRunTime((System.currentTimeMillis() - startTime));
            super.endTestSuite(suite);
        }
    }

    class JunitListener implements TestListener {

        public void addError(Test test, Throwable throwable) {
            Debug.logWarning(throwable, "[JUNIT (error)] - " + getTestName(test) + " : " + throwable.toString(), module);
        }

        public void addFailure(Test test, AssertionFailedError assertionFailedError) {
            Debug.logWarning("[JUNIT (failure)] - " + getTestName(test) + " : " + assertionFailedError.getMessage(), module);
        }

        public void endTest(Test test) {
            Debug.logInfo("[JUNIT] : " + getTestName(test) + " finished.", module);
        }

        public void startTest(Test test) {
           Debug.logInfo("[JUNIT] : " + getTestName(test) + " starting...", module);
        }

        private String getTestName(Test test) {
            if (test instanceof TestCase) {
                return ((TestCase)test).getName();
            } else {
                return test.getClass().getName();
            }

        }
    }
}
