package org.testng.reporters;


import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.collections.Lists;
import org.testng.internal.IResultListener;
import org.testng.internal.Utils;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/**
 * this XML Reporter will produce XML format compatible with the XMLJUnitResultFormatter from ant
 * this enables TestNG output to be processed by tools that already handle this format
 *
 * borrows heavily from ideas in org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter
 *
 * this is the original version which was replaced by JUnitXMLReporter
 * @TODO: clean up
 */
public class JUnitXMLReporter2 implements IResultListener {

  private String m_outputFileName= null;
  private File m_outputFile= null;
  private ITestContext m_testContext= null;

  /**
   * keep lists of all the results
   */
  private int m_numPassed= 0;
  private int m_numFailed= 0;
  private int m_numSkipped= 0;
  private int m_numFailedButIgnored= 0;
  private List<ITestResult> m_allTests
      = Collections.synchronizedList(Lists.<ITestResult>newArrayList());
  private List<ITestResult> m_configIssues
      = Collections.synchronizedList(Lists.<ITestResult>newArrayList());

  @Override
  public void onTestStart(ITestResult result) {
  }

  /**
   * Invoked each time a test succeeds.
   */
  @Override
  public void onTestSuccess(ITestResult tr) {
    m_allTests.add(tr);
    m_numPassed++;
  }

  @Override
  public void onTestFailedButWithinSuccessPercentage(ITestResult tr) {
    m_allTests.add(tr);
    m_numFailedButIgnored++;
  }

  /**
   * Invoked each time a test fails.
   */
  @Override
  public void onTestFailure(ITestResult tr) {
    m_allTests.add(tr);
    m_numFailed++;
  }

  /**
   * Invoked each time a test is skipped.
   */
  @Override
  public void onTestSkipped(ITestResult tr) {
    m_allTests.add(tr);
    m_numSkipped++;
  }

  /**
   * Invoked after the test class is instantiated and before
   * any configuration method is called.
   *
   */
  @Override
  public void onStart(ITestContext context) {
    m_outputFileName= context.getOutputDirectory() + File.separator + context.getName() + ".xml";
    m_outputFile= new File(m_outputFileName);
    m_testContext= context;
  }

  /**
   * Invoked after all the tests have run and all their
   * Configuration methods have been called.
   *
   */
  @Override
  public void onFinish(ITestContext context) {
    generateReport();
  }

  /**
   * generate the XML report given what we know from all the test results
   */
  protected void generateReport() {
    try {
      DocumentBuilderFactory docBuilderFactory= DocumentBuilderFactory.newInstance();
      docBuilderFactory.setNamespaceAware(true); // so we can transform it later
      DocumentBuilder docBuilder= docBuilderFactory.newDocumentBuilder();
      Document d= docBuilder.newDocument();
      Element rootElement= d.createElement(XMLConstants.TESTSUITE);
      rootElement.setAttribute(XMLConstants.ATTR_NAME, m_testContext.getName());

      Element propsElement= d.createElement(XMLConstants.PROPERTIES);
      rootElement.appendChild(propsElement);

      // properties. just TestNG properties or also System properties?

      rootElement.setAttribute(XMLConstants.ATTR_TESTS, "" + m_allTests.size());
      rootElement.setAttribute(XMLConstants.ATTR_FAILURES, "" + m_numFailed);
      rootElement.setAttribute(XMLConstants.ATTR_ERRORS, "0"); // FIXME

      long elapsedTimeMillis= m_testContext.getEndDate().getTime()
        - m_testContext.getStartDate().getTime();
      rootElement.setAttribute(XMLConstants.ATTR_TIME, "" + (elapsedTimeMillis / 1000.0));

      for(ITestResult tr: m_configIssues) {
        Element element= createElement(d, tr);
        rootElement.appendChild(element);
      }
      for(ITestResult tr : m_allTests) {
        Element testCaseElement= createElement(d, tr);
        rootElement.appendChild(testCaseElement);
      }

      BufferedWriter fw= new BufferedWriter(new FileWriter(m_outputFile));

      Transformer transformer= TransformerFactory.newInstance().newTransformer();
      transformer.transform(new DOMSource(rootElement), new StreamResult(fw));
      fw.flush();
      fw.close();
    }
    catch(IOException ioe) {
      ioe.printStackTrace();
      System.err.println("failed to create JUnitXML because of " + ioe);
    }
    catch(ParserConfigurationException pce) {
      pce.printStackTrace();
      System.err.println("failed to create JUnitXML because of " + pce);
    }
    catch(TransformerException te) {
      te.printStackTrace();
      System.err.println("Error while writing out JUnitXML because of " + te);
    }
  }

  private Element createElement(Document doc, ITestResult tr) {
    Element resultElement= doc.createElement(XMLConstants.TESTCASE);
    long elapsedTimeMillis= tr.getEndMillis() - tr.getStartMillis();
    String name= tr.getMethod().isTest() ? tr.getName() : Utils.detailedMethodName(tr.getMethod(), false);
    resultElement.setAttribute(XMLConstants.ATTR_NAME, name);
    resultElement.setAttribute(XMLConstants.ATTR_CLASSNAME,
                               tr.getTestClass().getRealClass().getName());
    resultElement.setAttribute(XMLConstants.ATTR_TIME,
                               "" + ((double) elapsedTimeMillis)/1000);
    if (ITestResult.FAILURE == tr.getStatus()) {
      Element nested = createFailureElement(doc, tr);
      resultElement.appendChild(nested);
    }
    else if (ITestResult.SKIP == tr.getStatus()) {
      Element nested = createSkipElement(doc, tr);
      resultElement.appendChild(nested);
    }

    return resultElement;
  }

  private Element createFailureElement(Document doc, ITestResult tr) {
    Element nested= doc.createElement(XMLConstants.FAILURE);
    Throwable t = tr.getThrowable();
    if (t != null) {
      nested.setAttribute(XMLConstants.ATTR_TYPE, t.getClass().getName());
      String message = t.getMessage();
      if ((message != null) && (message.length() > 0)) {
        nested.setAttribute(XMLConstants.ATTR_MESSAGE, message);
      }
      CDATASection trace= doc.createCDATASection(Utils.stackTrace(t, false)[0]);
      nested.appendChild(trace);
    }

    return nested;
  }

  private Element createSkipElement(Document doc, ITestResult tr) {
    return doc.createElement("skipped");
  }

  /**
   * @see org.testng.internal.IConfigurationListener#onConfigurationFailure(org.testng.ITestResult)
   */
  @Override
  public void onConfigurationFailure(ITestResult itr) {
    m_configIssues.add(itr);
  }

  /**
   * @see org.testng.internal.IConfigurationListener#onConfigurationSkip(org.testng.ITestResult)
   */
  @Override
  public void onConfigurationSkip(ITestResult itr) {
    m_configIssues.add(itr);
  }

  /**
   * @see org.testng.internal.IConfigurationListener#onConfigurationSuccess(org.testng.ITestResult)
   */
  @Override
  public void onConfigurationSuccess(ITestResult itr) {
  }
}
