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

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import org.apache.ant.antunit.AssertionFailedException;

import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Location;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.util.DateUtils;
import org.apache.tools.ant.util.DOMElementWriter;
import org.apache.tools.ant.util.DOMUtils;
import org.apache.tools.ant.util.StringUtils;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * A test listener for &lt;antunit&gt; modelled after the XML JUnit
 * test listener that is part of Ant.
 */
public class XMLAntUnitListener extends BaseAntUnitListener {
    private static final String INDENT = "  ";
    private OutputStream out = null;
    private Writer wri;
    private DOMElementWriter domWri = new DOMElementWriter(true);
    private Document doc;
    private Element root;
    private Element currentTest;
    /**
     * Collects log messages.
     */
    private StringBuffer log = new StringBuffer();

    public XMLAntUnitListener() {
        super(new BaseAntUnitListener.SendLogTo(SendLogTo.FILE), "xml");
    }

    public void startTestSuite(Project testProject, String buildFile) {
        try {
            super.startTestSuite(testProject, buildFile);
            out = getOut(buildFile);
            wri = new OutputStreamWriter(out, "UTF8");
            doc = DOMUtils.newDocument();
            root = doc.createElement(XMLConstants.TESTSUITE);
            // if we want to (ab)use <junitreport> name needs to
            // follow the structure expected by that task:
            // package.class.  package will be the directory holding
            // the build file (file separators replaced by dots) and
            // class the build file name with the last dot replaced
            // by an underscore
            root.setAttribute(XMLConstants.ATTR_NAME, normalize(buildFile));
            root.setAttribute(XMLConstants.BUILD_FILE, buildFile);

            //add the timestamp
            String timestamp = DateUtils.format(new Date(),
                                                DateUtils
                                                .ISO8601_DATETIME_PATTERN);
            root.setAttribute(XMLConstants.TIMESTAMP, timestamp);
            //and the hostname.
            root.setAttribute(XMLConstants.HOSTNAME, getHostname());

            domWri.writeXMLDeclaration(wri);
            domWri.openElement(root, wri, 0, INDENT, true);
            wri.write(StringUtils.LINE_SEP);

            Element propertiesElement =
                DOMUtils.createChildElement(root, XMLConstants.PROPERTIES);
            Hashtable propertiesMap = testProject.getProperties();
            for (final Iterator iterator = propertiesMap.entrySet().iterator(); 
                 iterator.hasNext();) {
                final Map.Entry property = (Map.Entry) iterator.next();
                Element e = DOMUtils.createChildElement(propertiesElement,
                                                        XMLConstants.PROPERTY);
                e.setAttribute(XMLConstants.ATTR_NAME,
                               property.getKey().toString());
                e.setAttribute(XMLConstants.ATTR_VALUE,
                               property.getValue().toString());
            }
            domWri.write(propertiesElement, wri, 1, INDENT);
        } catch (IOException ex) {
            throw new BuildException(ex);
        }
    }

    public void endTestSuite(Project testProject, String buildFile) {
        try {
            Element e;
            if (log.length() > 0) {
                e = DOMUtils.createChildElement(root, XMLConstants.SYSTEM_OUT);
                DOMUtils.appendCDATA(e, log.toString());
                log.setLength(0);
                domWri.write(e, wri, 1, INDENT);
            }
            e = DOMUtils.createChildElement(root, XMLConstants.ATTR_TESTS); 
            DOMUtils.appendText(e, String.valueOf(runCount));
            domWri.write(e, wri, 1, INDENT);
            e = DOMUtils.createChildElement(root, XMLConstants.ATTR_FAILURES);
            DOMUtils.appendText(e, String.valueOf(failureCount));
            domWri.write(e, wri, 1, INDENT);
            e = DOMUtils.createChildElement(root, XMLConstants.ATTR_ERRORS);
            DOMUtils.appendText(e, String.valueOf(errorCount));
            domWri.write(e, wri, 1, INDENT);
            e = DOMUtils.createChildElement(root, XMLConstants.ATTR_TIME);
            DOMUtils.appendText(e,
                                String.valueOf((System.currentTimeMillis()
                                                - start)
                                               / 1000.0));
            domWri.write(e, wri, 1, INDENT);

            domWri.closeElement(root, wri, 0, INDENT, true);

            wri.flush();
        } catch (IOException ex) {
            throw new BuildException(ex);
        } finally {
            close(out);
        }
    }

    public void startTest(String target) {
        try {
            super.startTest(target);
            currentTest = DOMUtils.createChildElement(root,
                                                      XMLConstants.TESTCASE);
            currentTest.setAttribute(XMLConstants.ATTR_NAME, target);
            domWri.openElement(currentTest, wri, 1, INDENT, true);
            wri.write(StringUtils.LINE_SEP);
        } catch (IOException ex) {
            throw new BuildException(ex);
        }
    }

    public void endTest(String target) {
        try {
            Element e = DOMUtils.createChildElement(currentTest,
                                                    XMLConstants.ATTR_TIME);
            DOMUtils.appendText(e,
                                String.valueOf((System.currentTimeMillis()
                                                - testStart)
                                               / 1000.0));
            domWri.write(e, wri, 2, INDENT);
            domWri.closeElement(currentTest, wri, 1, INDENT, true);
        } catch (IOException ex) {
            throw new BuildException(ex);
        }
    }

    public void addFailure(String target, AssertionFailedException ae) {
        super.addFailure(target, ae);
        formatError(XMLConstants.FAILURE, ae);
    }
    public void addError(String target, Throwable ae) {
        super.addError(target, ae);
        formatError(XMLConstants.ERROR, ae);
    }

    private void formatError(String type, Throwable t) {
        try {
            Element e = DOMUtils.createChildElement(currentTest, type);
            Location l = getLocation(t);
            if (l.getLineNumber() != 0) {
                e.setAttribute(XMLConstants.ATTR_LINE,
                               String.valueOf(l.getLineNumber()));
            }
            if (l.getColumnNumber() != 0) {
                e.setAttribute(XMLConstants.ATTR_COLUMN,
                               String.valueOf(l.getColumnNumber()));
            }
            String message = t.getMessage();
            if (message != null && message.length() > 0) {
                e.setAttribute(XMLConstants.ATTR_MESSAGE, t.getMessage());
            }
            e.setAttribute(XMLConstants.ATTR_TYPE, t.getClass().getName());
            DOMUtils.appendText(e, StringUtils.getStackTrace(t));
            domWri.write(e, wri, 2, INDENT);
        } catch (IOException ex) {
            throw new BuildException(ex);
        }
    }

    protected void messageLogged(BuildEvent event) {
        log.append(event.getMessage());
        log.append(System.getProperty("line.separator"));
    }

    /**
     * get the local hostname - stolen from junit.XMLJUnitResultFormatter
     * @return the name of the local host, or "localhost" if we cannot
     * work it out
     */
    private String getHostname()  {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            return "localhost";
        }
    }

}
