/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 com.android.regression.tests;

import com.android.tradefed.result.MetricsXMLResultReporter;
import com.android.tradefed.result.TestDescription;

import com.google.common.annotations.VisibleForTesting;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/** Parser that extracts test metrics result data generated by {@link MetricsXMLResultReporter}. */
public class MetricsXmlParser {

    /** Thrown when MetricsXmlParser fails to parse a metrics xml file. */
    @SuppressWarnings("serial")
    public static class ParseException extends Exception {
        public ParseException(Throwable cause) {
            super(cause);
        }

        public ParseException(String msg, Throwable cause) {
            super(msg, cause);
        }
    }

    /*
     * Parses the xml format. Expected tags/attributes are:
     * testsuite name="runname" tests="X"
     *   runmetric name="metric1" value="1.0"
     *   testcase classname="FooTest" testname="testMethodName"
     *     testmetric name="metric2" value="1.0"
     */
    private static class MetricsXmlHandler extends DefaultHandler {

        private static final String TESTSUITE_TAG = "testsuite";
        private static final String TESTCASE_TAG = "testcase";
        private static final String TIME_TAG = "time";
        private static final String RUNMETRIC_TAG = "runmetric";
        private static final String TESTMETRIC_TAG = "testmetric";

        private TestDescription mCurrentTest = null;

        private Metrics mMetrics;
        private Set<String> mBlocklistMetrics;

        public MetricsXmlHandler(Metrics metrics, Set<String> blocklistMetrics) {
            mMetrics = metrics;
            mBlocklistMetrics = blocklistMetrics;
        }

        @Override
        public void startElement(String uri, String localName, String name, Attributes attributes)
                throws SAXException {
            if (TESTSUITE_TAG.equalsIgnoreCase(name)) {
                // top level tag - maps to a test run in TF terminology
                String testCount = getMandatoryAttribute(name, "tests", attributes);
                mMetrics.setNumTests(Integer.parseInt(testCount));
                mMetrics.addRunMetric(TIME_TAG, getMandatoryAttribute(name, TIME_TAG, attributes));
            }
            if (TESTCASE_TAG.equalsIgnoreCase(name)) {
                // start of description of an individual test method
                String testClassName = getMandatoryAttribute(name, "classname", attributes);
                String methodName = getMandatoryAttribute(name, "testname", attributes);
                mCurrentTest = new TestDescription(testClassName, methodName);
            }
            if (RUNMETRIC_TAG.equalsIgnoreCase(name)) {
                String metricName = getMandatoryAttribute(name, "name", attributes);
                String metricValue = getMandatoryAttribute(name, "value", attributes);
                if (!mBlocklistMetrics.contains(metricName)) {
                    mMetrics.addRunMetric(metricName, metricValue);
                }
            }
            if (TESTMETRIC_TAG.equalsIgnoreCase(name)) {
                String metricName = getMandatoryAttribute(name, "name", attributes);
                String metricValue = getMandatoryAttribute(name, "value", attributes);
                if (!mBlocklistMetrics.contains(metricName)) {
                    mMetrics.addTestMetric(mCurrentTest, metricName, metricValue);
                }
            }
        }

        private String getMandatoryAttribute(String tagName, String attrName, Attributes attributes)
                throws SAXException {
            String value = attributes.getValue(attrName);
            if (value == null) {
                throw new SAXException(
                        String.format(
                                "Malformed XML, could not find '%s' attribute in '%s'",
                                attrName, tagName));
            }
            return value;
        }
    }

    /**
     * Parses xml data contained in given input files.
     *
     * @param blocklistMetrics ignore the metrics with these names
     * @param strictMode whether to throw an exception when metric validation fails
     * @param metricXmlFiles a list of metric xml files
     * @return a Metric object containing metrics from all metric files
     * @throws ParseException if input could not be parsed
     */
    public static Metrics parse(
            Set<String> blocklistMetrics, boolean strictMode, List<File> metricXmlFiles)
            throws ParseException {
        Metrics metrics = new Metrics(strictMode);
        for (File xml : metricXmlFiles) {
            try (InputStream is = new BufferedInputStream(new FileInputStream(xml))) {
                parse(metrics, blocklistMetrics, is);
            } catch (Exception e) {
                throw new ParseException("Unable to parse " + xml.getPath(), e);
            }
        }
        metrics.validate(metricXmlFiles.size());
        return metrics;
    }

    @VisibleForTesting
    public static Metrics parse(Metrics metrics, Set<String> blocklistMetrics, InputStream is)
            throws ParseException {
        try {
            SAXParserFactory parserFactory = SAXParserFactory.newInstance();
            parserFactory.setNamespaceAware(true);
            SAXParser parser = parserFactory.newSAXParser();
            parser.parse(is, new MetricsXmlHandler(metrics, blocklistMetrics));
            return metrics;
        } catch (ParserConfigurationException | SAXException | IOException e) {
            throw new ParseException(e);
        }
    }
}
