/*
 *  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
 *
 *      https://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.tools.ant.taskdefs.optional.junitlauncher;

import org.apache.tools.ant.util.DOMElementWriter;
import org.apache.tools.ant.util.DateUtils;
import org.apache.tools.ant.util.StringUtils;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.TestSource;
import org.junit.platform.engine.reporting.ReportEntry;
import org.junit.platform.engine.support.descriptor.ClassSource;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.util.Date;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * A {@link TestResultFormatter} which generates an XML report of the tests. The generated XML reports
 * conforms to the schema of the XML that was generated by the {@code junit} task's XML
 * report formatter and can be used by the {@code junitreport} task
 */
class LegacyXmlResultFormatter extends AbstractJUnitResultFormatter implements TestResultFormatter {

    private static final double ONE_SECOND = 1000.0;

    private OutputStream outputStream;
    private final Map<TestIdentifier, Stats> testIds = new ConcurrentHashMap<>();
    private final Map<TestIdentifier, Optional<String>> skipped = new ConcurrentHashMap<>();
    private final Map<TestIdentifier, Optional<Throwable>> failed = new ConcurrentHashMap<>();
    private final Map<TestIdentifier, Optional<Throwable>> aborted = new ConcurrentHashMap<>();

    private TestPlan testPlan;
    private long testPlanStartedAt = -1;
    private long testPlanEndedAt = -1;
    private final AtomicLong numTestsRun = new AtomicLong(0);
    private final AtomicLong numTestsFailed = new AtomicLong(0);
    private final AtomicLong numTestsSkipped = new AtomicLong(0);
    private final AtomicLong numTestsAborted = new AtomicLong(0);


    @Override
    public void testPlanExecutionStarted(final TestPlan testPlan) {
        this.testPlan = testPlan;
        this.testPlanStartedAt = System.currentTimeMillis();
    }

    @Override
    public void testPlanExecutionFinished(final TestPlan testPlan) {
        this.testPlanEndedAt = System.currentTimeMillis();
        // format and print out the result
        try {
            new XMLReportWriter().write();
        } catch (IOException | XMLStreamException e) {
            handleException(e);
        }
    }

    @Override
    public void dynamicTestRegistered(final TestIdentifier testIdentifier) {
        // nothing to do
    }

    @Override
    public void executionSkipped(final TestIdentifier testIdentifier, final String reason) {
        final long currentTime = System.currentTimeMillis();
        this.numTestsSkipped.incrementAndGet();
        this.skipped.put(testIdentifier, Optional.ofNullable(reason));
        // a skipped test is considered started and ended now
        final Stats stats = new Stats(testIdentifier, currentTime);
        stats.endedAt = currentTime;
        this.testIds.put(testIdentifier, stats);
    }

    @Override
    public void executionStarted(final TestIdentifier testIdentifier) {
        final long currentTime = System.currentTimeMillis();
        this.testIds.putIfAbsent(testIdentifier, new Stats(testIdentifier, currentTime));
        if (testIdentifier.isTest()) {
            this.numTestsRun.incrementAndGet();
        }
    }

    @Override
    public void executionFinished(final TestIdentifier testIdentifier, final TestExecutionResult testExecutionResult) {
        final long currentTime = System.currentTimeMillis();
        final Stats stats = this.testIds.get(testIdentifier);
        if (stats != null) {
            stats.endedAt = currentTime;
        }
        switch (testExecutionResult.getStatus()) {
            case SUCCESSFUL: {
                break;
            }
            case ABORTED: {
                this.numTestsAborted.incrementAndGet();
                this.aborted.put(testIdentifier, testExecutionResult.getThrowable());
                break;
            }
            case FAILED: {
                this.numTestsFailed.incrementAndGet();
                this.failed.put(testIdentifier, testExecutionResult.getThrowable());
                break;
            }
        }
    }

    @Override
    public void reportingEntryPublished(final TestIdentifier testIdentifier, final ReportEntry entry) {
        // nothing to do
    }

    @Override
    public void setDestination(final OutputStream os) {
        this.outputStream = os;
    }

    private final class Stats {
        @SuppressWarnings("unused")
        private final TestIdentifier testIdentifier;
        private final long startedAt;
        private long endedAt;

        private Stats(final TestIdentifier testIdentifier, final long startedAt) {
            this.testIdentifier = testIdentifier;
            this.startedAt = startedAt;
        }
    }

    private final class XMLReportWriter {

        private static final String ELEM_TESTSUITE = "testsuite";
        private static final String ELEM_PROPERTIES = "properties";
        private static final String ELEM_PROPERTY = "property";
        private static final String ELEM_TESTCASE = "testcase";
        private static final String ELEM_SKIPPED = "skipped";
        private static final String ELEM_FAILURE = "failure";
        private static final String ELEM_ABORTED = "aborted";
        private static final String ELEM_SYSTEM_OUT = "system-out";
        private static final String ELEM_SYSTEM_ERR = "system-err";


        private static final String ATTR_CLASSNAME = "classname";
        private static final String ATTR_NAME = "name";
        private static final String ATTR_VALUE = "value";
        private static final String ATTR_TIME = "time";
        private static final String ATTR_TIMESTAMP = "timestamp";
        private static final String ATTR_NUM_ABORTED = "aborted";
        private static final String ATTR_NUM_FAILURES = "failures";
        private static final String ATTR_NUM_TESTS = "tests";
        private static final String ATTR_NUM_SKIPPED = "skipped";
        private static final String ATTR_MESSAGE = "message";
        private static final String ATTR_TYPE = "type";

        void write() throws XMLStreamException, IOException {
            final XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(outputStream, "UTF-8");
            try {
                writer.writeStartDocument();
                writeTestSuite(writer);
                writer.writeEndDocument();
            } finally {
                writer.close();
            }
        }

        void writeTestSuite(final XMLStreamWriter writer) throws XMLStreamException, IOException {
            // write the testsuite element
            writer.writeStartElement(ELEM_TESTSUITE);
            final String testsuiteName = determineTestSuiteName();
            writer.writeAttribute(ATTR_NAME, testsuiteName);
            // time taken for the tests execution
            writer.writeAttribute(ATTR_TIME, String.valueOf((testPlanEndedAt - testPlanStartedAt) / ONE_SECOND));
            // add the timestamp of report generation
            final String timestamp = DateUtils.format(new Date(), DateUtils.ISO8601_DATETIME_PATTERN);
            writer.writeAttribute(ATTR_TIMESTAMP, timestamp);
            writer.writeAttribute(ATTR_NUM_TESTS, String.valueOf(numTestsRun.longValue()));
            writer.writeAttribute(ATTR_NUM_FAILURES, String.valueOf(numTestsFailed.longValue()));
            writer.writeAttribute(ATTR_NUM_SKIPPED, String.valueOf(numTestsSkipped.longValue()));
            writer.writeAttribute(ATTR_NUM_ABORTED, String.valueOf(numTestsAborted.longValue()));

            // write the properties
            writeProperties(writer);
            // write the tests
            writeTestCase(writer);
            writeSysOut(writer);
            writeSysErr(writer);
            // end the testsuite
            writer.writeEndElement();
        }

        void writeProperties(final XMLStreamWriter writer) throws XMLStreamException {
            final Properties properties = LegacyXmlResultFormatter.this.context.getProperties();
            if (properties == null || properties.isEmpty()) {
                return;
            }
            writer.writeStartElement(ELEM_PROPERTIES);
            for (final String prop : properties.stringPropertyNames()) {
                writer.writeStartElement(ELEM_PROPERTY);
                writer.writeAttribute(ATTR_NAME, prop);
                writer.writeAttribute(ATTR_VALUE, properties.getProperty(prop));
                writer.writeEndElement();
            }
            writer.writeEndElement();
        }

        void writeTestCase(final XMLStreamWriter writer) throws XMLStreamException {
            for (final Map.Entry<TestIdentifier, Stats> entry : testIds.entrySet()) {
                final TestIdentifier testId = entry.getKey();
                if (!testId.isTest() && !failed.containsKey(testId)) {
                    // only interested in test methods unless there was a failure,
                    // in which case we want the exception reported
                    // (https://bz.apache.org/bugzilla/show_bug.cgi?id=63850)
                    continue;
                }
                // find the associated class of this test
                final Optional<ClassSource> parentClassSource;
                if (testId.isTest()) {
                    parentClassSource = findFirstParentClassSource(testId);
                }
                else {
                    parentClassSource = findFirstClassSource(testId);
                }
                if (!parentClassSource.isPresent()) {
                    continue;
                }
                final String classname = (parentClassSource.get()).getClassName();
                writer.writeStartElement(ELEM_TESTCASE);
                writer.writeAttribute(ATTR_CLASSNAME, classname);
                writer.writeAttribute(ATTR_NAME, testId.getLegacyReportingName());
                final Stats stats = entry.getValue();
                writer.writeAttribute(ATTR_TIME, String.valueOf((stats.endedAt - stats.startedAt) / ONE_SECOND));
                // skipped element if the test was skipped
                writeSkipped(writer, testId);
                // failed element if the test failed
                writeFailed(writer, testId);
                // aborted element if the test was aborted
                writeAborted(writer, testId);

                writer.writeEndElement();
            }
        }

        private void writeSkipped(final XMLStreamWriter writer, final TestIdentifier testIdentifier) throws XMLStreamException {
            if (!skipped.containsKey(testIdentifier)) {
                return;
            }
            writer.writeStartElement(ELEM_SKIPPED);
            final Optional<String> reason = skipped.get(testIdentifier);
            if (reason.isPresent()) {
                writer.writeAttribute(ATTR_MESSAGE, reason.get());
            }
            writer.writeEndElement();
        }

        private void writeFailed(final XMLStreamWriter writer, final TestIdentifier testIdentifier) throws XMLStreamException {
            if (!failed.containsKey(testIdentifier)) {
                return;
            }
            writer.writeStartElement(ELEM_FAILURE);
            final Optional<Throwable> cause = failed.get(testIdentifier);
            if (cause.isPresent()) {
                final Throwable t = cause.get();
                final String message = t.getMessage();
                if (message != null && !message.trim().isEmpty()) {
                    writer.writeAttribute(ATTR_MESSAGE, message);
                }
                writer.writeAttribute(ATTR_TYPE, t.getClass().getName());
                // write out the stacktrace
                writer.writeCData(StringUtils.getStackTrace(t));
            }
            writer.writeEndElement();
        }

        private void writeAborted(final XMLStreamWriter writer, final TestIdentifier testIdentifier) throws XMLStreamException {
            if (!aborted.containsKey(testIdentifier)) {
                return;
            }
            writer.writeStartElement(ELEM_ABORTED);
            final Optional<Throwable> cause = aborted.get(testIdentifier);
            if (cause.isPresent()) {
                final Throwable t = cause.get();
                final String message = t.getMessage();
                if (message != null && !message.trim().isEmpty()) {
                    writer.writeAttribute(ATTR_MESSAGE, message);
                }
                writer.writeAttribute(ATTR_TYPE, t.getClass().getName());
                // write out the stacktrace
                writer.writeCData(StringUtils.getStackTrace(t));
            }
            writer.writeEndElement();
        }

        private void writeSysOut(final XMLStreamWriter writer) throws XMLStreamException, IOException {
            if (!LegacyXmlResultFormatter.this.hasSysOut()) {
                return;
            }
            writer.writeStartElement(ELEM_SYSTEM_OUT);
            try (final Reader reader = LegacyXmlResultFormatter.this.getSysOutReader()) {
                writeCharactersFrom(reader, writer);
            }
            writer.writeEndElement();
        }

        private void writeSysErr(final XMLStreamWriter writer) throws XMLStreamException, IOException {
            if (!LegacyXmlResultFormatter.this.hasSysErr()) {
                return;
            }
            writer.writeStartElement(ELEM_SYSTEM_ERR);
            try (final Reader reader = LegacyXmlResultFormatter.this.getSysErrReader()) {
                writeCharactersFrom(reader, writer);
            }
            writer.writeEndElement();
        }

        private void writeCharactersFrom(final Reader reader, final XMLStreamWriter writer) throws IOException, XMLStreamException {
            final char[] chars = new char[1024];
            int numRead = -1;
            while ((numRead = reader.read(chars)) != -1) {
                // although it's called a DOMElementWriter, the encode method is just a
                // straight forward XML util method which doesn't concern about whether
                // DOM, SAX, StAX semantics.
                // TODO: Perhaps make it a static method
                final String encoded = new DOMElementWriter().encode(new String(chars, 0, numRead));
                writer.writeCharacters(encoded);
            }
        }

        private String determineTestSuiteName() {
            // this is really a hack to try and match the expectations of the XML report in JUnit4.x
            // world. In JUnit5, the TestPlan doesn't have a name and a TestPlan (for which this is a
            // listener) can have numerous tests within it
            final Set<TestIdentifier> roots = testPlan.getRoots();
            if (roots.isEmpty()) {
                return "UNKNOWN";
            }
            for (final TestIdentifier root : roots) {
                final Optional<ClassSource> classSource = findFirstClassSource(root);
                if (classSource.isPresent()) {
                    return classSource.get().getClassName();
                }
            }
            return "UNKNOWN";
        }

        private Optional<ClassSource> findFirstClassSource(final TestIdentifier root) {
            if (root.getSource().isPresent()) {
                final TestSource source = root.getSource().get();
                if (source instanceof ClassSource) {
                    return Optional.of((ClassSource) source);
                }
            }
            for (final TestIdentifier child : testPlan.getChildren(root)) {
                final Optional<ClassSource> classSource = findFirstClassSource(child);
                if (classSource.isPresent()) {
                    return classSource;
                }
            }
            return Optional.empty();
        }

        private Optional<ClassSource> findFirstParentClassSource(final TestIdentifier testId) {
            final Optional<TestIdentifier> parent = testPlan.getParent(testId);
            if (!parent.isPresent() || !parent.get().getSource().isPresent()) {
                return Optional.empty();
            }
            final TestSource parentSource = parent.get().getSource().get();
            return parentSource instanceof ClassSource ? Optional.of((ClassSource) parentSource)
                    : findFirstParentClassSource(parent.get());
        }
    }

}
