/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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 tools.JUnit;

import java.util.*;

import java.io.*;

import java.text.SimpleDateFormat;



import junit.framework.Test;

import junit.framework.AssertionFailedError;

import junit.framework.TestCase;



import noNamespace.TestResultContainerDocument.TestResultContainer;

import noNamespace.*;

import noNamespace.TestResultType.ExecutionOutput;

import org.apache.xmlbeans.XmlOptions;

import tools.io.TeeOutputStream;

import org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner;

/**
 * Implementation of JUnitXResultFormatter that records JUnit results
 * and publishes the result as a XML Document
 */
public class XmlResultFormatterImpl implements JUnitXResultFormatter
{
    public static int TEST_SUCCESS = 0;
    public static int TEST_FAILURE = 1;
    public static int TEST_ERROR = 2;
    public static int TEST_UNKNOWN = 3;

    // Lets capture STDOUT and STDERR
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    ByteArrayOutputStream bErr = new ByteArrayOutputStream();

    TeeOutputStream tOut;
    TeeOutputStream tErr;

    PrintStream _out;
    PrintStream _err;

    private TestRecord testRecord;
    Collection records;

    // By default write to StdOut
    OutputStream logOut = System.out;

    // Record Stats
    int testCount = 0;
    int passCount = 0;
    int failCount = 0;
    long startTime = 0;

    boolean showOutput = false;

    public void startRun()
    {
        records = new ArrayList();

        // Reset stats
        testCount = 0;
        passCount = 0;
        failCount = 0;
        startTime = System.currentTimeMillis();
    }

    public void endRun()
    {
        System.out.println("=================================================");
        System.out.println("Tests Ran: " + testCount);
        System.out.println("Success:   " + passCount);
        System.out.println("Failures:  " + failCount);

        // Generate log:
        System.out.println("Starting Publish: " + System.currentTimeMillis());
        publishResults();
        System.out.println("Finished Publish: " + System.currentTimeMillis());
    }

    public void setOutput(OutputStream out)
    {
        if (out != null)
            logOut = out;
    }

    public void showTestOutput(boolean show)
    {
        showOutput = show;
    }

    public void info(Object msg)
    {
        if (showOutput)
            System.out.println(msg);
    }

    /*
    * Implementation of TestListener
    */
	public synchronized void startTest(Test test)
    {
        String fullTestName = test.toString();
        info("Starting Test: " + fullTestName);

        // Lets start the capture
        System.out.flush();
        System.err.flush();

        _out = System.out;
        _err = System.err;

        bOut.reset();
        bErr.reset();

        // Redirect Stdout & Stderr to both console and our capture stream
        if (showOutput)
        {
            tOut = new TeeOutputStream(_out, bOut);
            tErr = new TeeOutputStream(_err, bErr);
            System.setOut(new PrintStream(tOut));
            System.setErr(new PrintStream(tErr));
        }
        else
        {
            System.setOut(new PrintStream(bOut));
            System.setErr(new PrintStream(bErr));
        }

        // Discard the previous record
        testRecord = new TestRecord(fullTestName);
        testRecord.setStartTime(System.currentTimeMillis());
	}

	public synchronized void endTest(Test test)
    {
        long endTime = System.currentTimeMillis();

        System.out.flush();
        System.err.flush();

        // Update the test record
        testRecord.setSysout(bOut.toString());
        testRecord.setSyserr(bErr.toString());
        testRecord.setEndTime(endTime);

        // this is a little hack for our reporting..
        // We could be on shaky ground if the behaviour of the JUnit task
        // ever changes.. OH Well...
        String fullTestName = test.toString();

        // Test-unit is between '(' and ')'
        int startindex = fullTestName.indexOf("(");
        int lastindex = fullTestName.indexOf(")");

        String testUnit;
        if (startindex >= 0 && lastindex > startindex)
            testUnit = fullTestName.substring(startindex+1, lastindex);
        else
            testUnit = fullTestName;

        String testMethod = ((TestCase) test).getName();

        // Get the last token from testUnit for the logical name
        startindex = testUnit.lastIndexOf(".");
        String baseClass = testUnit.substring(startindex+1);

        // update the extra fields of TestRecord
        testRecord.setTestUnitName(testUnit);
        testRecord.setTestLogicalName(baseClass + "." + testMethod);

        // If the test did not fail, record it as a success
        if (!testRecord.isFailure())
        {
            testRecord.setStatus(TEST_SUCCESS);
            passCount++;
        }
        else
            failCount++;

        testCount++;

        // Add it to the set
        records.add(testRecord);

        // set testRecord to null..
        // Restore STDOUT and STDERR
        System.setOut(_out);
        System.setErr(_err);

        info("Finished Test: " + fullTestName + " "
                           + testRecord.getStatusString() + "\n");

        // Reset TestRecord
        testRecord = null;
	}

	public synchronized void addError(final Test test, final Throwable t)
    {
        if (testRecord == null)
            testRecord = getMissingTestRecord();

        testRecord.setStatus(TEST_ERROR);
        testRecord.setThrowable(t);

        // Special case when test class is missing...
        if (t.toString().indexOf("ClassNotFoundException") > -1)
        {
            records.add(testRecord);
            testRecord = null;
        }
	}

	public synchronized void addFailure(final Test test, final AssertionFailedError t)
    {
        if (testRecord == null)
            testRecord = getMissingTestRecord();

        testRecord.setStatus(TEST_FAILURE);
        testRecord.setThrowable(t);
	}

    /**
     * Utility class to record per test data like test name, status, start
     * and end time, STDOUT, STDERR from text execution etc.
     */
    private class TestRecord
    {
        public TestRecord(String name)
        {
            setTestname(name);
        }

        private String testname;
        private String sysout;
        private String syserr;

        private Throwable t;

        private long startTime;
        private long endTime;

        private int status;
        boolean failed = false;

        private String testUnitName;
        private String testLogicalName;

        public void setTestname(String name)
        {
            this.testname = name;
        }

        public String getTestname()
        {
            return testname;
        }

        public void setStatus(int status)
        {
            this.status = status;

            if (status == TEST_ERROR || status == TEST_FAILURE)
                failed = true;
        }

        public int getStatus()
        {
            return status;
        }

        public String getStatusString()
        {
            return (status == TEST_SUCCESS)?"SUCCESS":
                        (status == TEST_ERROR)?"ERROR":"FAILURE";
        }

        public boolean isFailure()
        {
            return failed;
        }

        public String getSysout()
        {
            return sysout;
        }

        public void setSysout(String sysout)
        {
            this.sysout = sysout;
        }

        public String getSyserr()
        {
            return syserr;
        }

        public void setSyserr(String syserr)
        {
            this.syserr = syserr;
        }

        public Throwable getThrowable()
        {
            return t;
        }

        public void setThrowable(Throwable t)
        {
            this.t = t;
        }

       public long getStartTime()
        {
            return startTime;
        }

        public void setStartTime(long startTime)
        {
            this.startTime = startTime;
        }

        public long getEndTime()
        {
            return endTime;
        }

        public void setEndTime(long endTime)
        {
            this.endTime = endTime;
        }

        public String getTestUnitName()
        {
            return testUnitName;
        }

        public void setTestUnitName(String testUnitName)
        {
            this.testUnitName = testUnitName;
        }

        public String getTestLogicalName()
        {
            return testLogicalName;
        }

        public void setTestLogicalName(String testLogicalName)
        {
            this.testLogicalName = testLogicalName;
        }

    }

    private TestRecord getMissingTestRecord()
    {
        TestRecord tr = new TestRecord("Missing");
        tr.setStartTime(System.currentTimeMillis());
        tr.setEndTime(System.currentTimeMillis());
        tr.setStatus(TEST_ERROR);
        tr.setTestLogicalName("Missing");
        tr.setTestUnitName("Missing");
        return tr;
    }

    public void publishResults()
    {
        TestLogDocument logDoc = TestLogDocument.Factory.newInstance();
        TestLogDocument.TestLog log = logDoc.addNewTestLog();

        // Populate the attributes for test-log
        // testtype
        String testtype = System.getProperty("TESTTYPE", "AUTO");

        if (testtype.equalsIgnoreCase("AUTO"))
            log.setTesttype(TestLogDocument.TestLog.Testtype.AUTOMATED);
        else
            log.setTesttype(TestLogDocument.TestLog.Testtype.MANUAL);

        // runid
        String dateFormatStr = "_yy_MMM_dd_HH_mm_ss_SS";
        String dateStr = new SimpleDateFormat(dateFormatStr).format(new java.util.Date(startTime));
        String defRunId = System.getProperty("user.name").toUpperCase() + dateStr;
        String runId = System.getProperty("RUNID", defRunId);
        log.setRunid(runId);

        // hostname
        String hostname;

        try
        {
            hostname = java.net.InetAddress.getLocalHost().getHostName();
        } catch (Exception e)
        {
            // Ignore.. not critical
            hostname = "UNKNOWN_HOST";
        }

        log.setHostname(hostname);

        // TODO: set Defaults/check sysprop for other attributes

        // Add <environment> element
        EnvironmentType env = log.addNewEnvironment();
        Map envMap = new HashMap();
        envMap.put("JVM_NAME", System.getProperty("java.vm.name"));
        envMap.put("JVM_VENDOR", System.getProperty("java.vm.vendor"));
        envMap.put("JVM_VERSION", System.getProperty("java.vm.version"));
        envMap.put("OS", System.getProperty("os.name"));
        String defFreq = "checkin";
        envMap.put("Frequency", System.getProperty("test.run.frequency", defFreq));

        Iterator itr = envMap.keySet().iterator();

        int envCount = 0;
        while (itr.hasNext())
        {
            EnvironmentType.EnvAttribute envAttr = env.addNewEnvAttribute();
            String name = (String) itr.next();
            String value = (String) envMap.get(name);
            envAttr.setValue(value);
            envAttr.setName(name);
        }

        // Add <header-info> element
        TestLogDocument.TestLog.HeaderInfo hdrInfo = log.addNewHeaderInfo();
        hdrInfo.setResultcount(Integer.toString(testCount));
        hdrInfo.setChecksum(Integer.toString(testCount));
        hdrInfo.setExecdate(new java.util.Date(startTime).toString());
        hdrInfo.setExecaccount(System.getProperty("user.name"));

        // Add test-results
        Iterator rItr = records.iterator();

        while (rItr.hasNext())
        {
            TestResultType tr = log.addNewTestResult();
            tr.set(getTestResultType((TestRecord) rItr.next()));
        }

        // Publish it to the outputStream
        XmlOptions opts = new XmlOptions().setSavePrettyPrint();
        try
        {
            logOut.write(logDoc.xmlText(opts).getBytes());
        } catch (IOException ioe)
        {
            System.out.println("XmlResultFormatter: Unable to publish results");
            System.out.println(ioe.toString());
        }

    }

     /**
     * Creates the TestResultDocument and returns the Xml
     */
    private TestResultType getTestResultType(TestRecord rec)
    {
        TestResultType tr = TestResultType.Factory.newInstance();

        // Children of TestResult
        TestResultType.TestCase tc = tr.addNewTestCase();
        TestResultType.ExecutionOutput exo = tr.addNewExecutionOutput();

        // Set the logical test name... 'Class.Methodname'
        tr.setLogicalname(rec.getTestLogicalName());

        // Set the test Start time as a String
        tr.setExectime(new java.util.Date(rec.getStartTime()).toString());

        String status = rec.getStatusString();

        // Set the test result
        if (status.equals("SUCCESS"))
            tr.setResult(TestResultType.Result.SUCCESS);
        else if (status.equals("FAILURE"))
            tr.setResult(TestResultType.Result.FAILURE);
        else
            tr.setResult(TestResultType.Result.ABORT);

        // Set the test execution time.. in milliseconds
        String dur = java.lang.Long.toString(rec.getEndTime() - rec.getStartTime());
        tr.setDuration(dur);

        // Set the completion status..
        tr.setIsdone(TestResultType.Isdone.TRUE);

        // Setup the children elements
        // test-case
        tc.setTestcasename(rec.getTestLogicalName());
        tc.setTestunit(rec.getTestUnitName());

        // This should ideally be the whole path to the class...
        tc.setTestpath(rec.getTestname());

        // execution-output
        // if FAILURE.. set erroname attribute
        if (rec.isFailure())
        {
            String exp = rec.getThrowable().toString();
            int index = exp.indexOf(":");

            // the above line is very flaky..
            if (index < 0) index = exp.length();

            exo.setErrorname(exp.substring(0, index));
        }

        StringBuilder output = new StringBuilder();
        String eol = System.getProperty("line.separator");
        output.append("[STDOUT]").append(eol);
        output.append(rec.getSysout()).append(eol);
        output.append("[STDERR]").append(eol);
        output.append(rec.getSyserr()).append(eol);

        if (rec.isFailure())
        {
            output.append("[EXCEPTION]").append(eol);
            output.append(JUnitTestRunner.getFilteredTrace(rec.getThrowable()));
        }

        exo.setOutputDetails(output.toString());

        return tr;
    }

}

