/*
 * Copyright (C) 2010 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.cts.tradefed.testtype;

import com.android.cts.util.AbiUtils;
import com.android.ddmlib.Log;
import com.android.ddmlib.testrunner.TestIdentifier;
import com.android.tradefed.util.xml.AbstractXmlParser;

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

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

/**
 * Parser for CTS test case XML.
 * <p/>
 * Dumb parser that just retrieves data from in the test case xml and stuff it into a
 * {@link TestPackageDef}. Currently performs limited error checking.
 */
public class TestPackageXmlParser extends AbstractXmlParser {

    private static final String LOG_TAG = "TestPackageXmlParser";

    private final boolean mIncludeKnownFailures;

    private Map<String, TestPackageDef> mPackageDefs = new HashMap<String, TestPackageDef>();

    /**
     * @param includeKnownFailures Whether to run tests which are known to fail.
     */
    public TestPackageXmlParser(boolean includeKnownFailures) {
        mIncludeKnownFailures = includeKnownFailures;
    }

    /**
     * SAX callback object. Handles parsing data from the xml tags.
     * <p/>
     * Expected structure:
     * <TestPackage>
     *     <TestSuite ...>
     *        <TestCase>
     *           <Test>
     *             <TestInstance> (optional)
     */
    private class TestPackageHandler extends DefaultHandler {

        private static final String TEST_PACKAGE_TAG = "TestPackage";
        private static final String TEST_SUITE_TAG = "TestSuite";
        private static final String TEST_CASE_TAG = "TestCase";
        private static final String TEST_TAG = "Test";
        private static final String TEST_INSTANCE_TAG = "TestInstance";

        // holds current class name segments
        private Stack<String> mClassNameStack = new Stack<String>();
        private TestIdentifier mTestId;

        @Override
        public void startElement(String uri, String localName, String name, Attributes attributes) {
            if (TEST_PACKAGE_TAG.equals(localName)) {
                final String appPackageName = attributes.getValue("appPackageName");
                final String testPackageNameSpace = attributes.getValue("appNameSpace");
                final String packageName = attributes.getValue("name");
                final String runnerName = attributes.getValue("runner");
                final String jarPath = attributes.getValue("jarPath");
                final String javaPackageFilter = attributes.getValue("javaPackageFilter");
                final String targetBinaryName = attributes.getValue("targetBinaryName");
                final String targetNameSpace = attributes.getValue("targetNameSpace");
                final String runTimeArgs = attributes.getValue("runtimeArgs");
                final String testType = getTestType(attributes);

                for (String abiName : AbiUtils.getAbisSupportedByCts()) {
                    Abi abi = new Abi(abiName, AbiUtils.getBitness(abiName));
                    TestPackageDef packageDef = new TestPackageDef();
                    packageDef.setAppPackageName(appPackageName);
                    packageDef.setAppNameSpace(testPackageNameSpace);
                    packageDef.setName(packageName);
                    packageDef.setRunner(runnerName);
                    packageDef.setTestType(testType);
                    packageDef.setJarPath(jarPath);
                    packageDef.setRunTimeArgs(runTimeArgs);
                    if (!"".equals(javaPackageFilter)) {
                        packageDef.setTestPackageName(javaPackageFilter);
                    }
                    packageDef.setTargetBinaryName(targetBinaryName);
                    packageDef.setTargetNameSpace(targetNameSpace);
                    packageDef.setAbi(abi);
                    mPackageDefs.put(abiName, packageDef);
                }

                // reset the class name
                mClassNameStack = new Stack<String>();
            } else if (TEST_SUITE_TAG.equals(localName)) {
                String packageSegment = attributes.getValue("name");
                if (packageSegment != null) {
                    mClassNameStack.push(packageSegment);
                } else {
                    Log.e(LOG_TAG, String.format("Invalid XML: missing 'name' attribute for '%s'",
                            TEST_SUITE_TAG));
                }
            } else if (TEST_CASE_TAG.equals(localName)) {
                String classSegment = attributes.getValue("name");
                if (classSegment != null) {
                    mClassNameStack.push(classSegment);
                } else {
                    Log.e(LOG_TAG, String.format("Invalid XML: missing 'name' attribute for '%s'",
                            TEST_CASE_TAG));
                }
            } else if (TEST_TAG.equals(localName)) {
                String methodName = attributes.getValue("name");
                if (mPackageDefs.isEmpty()) {
                    Log.e(LOG_TAG, String.format(
                            "Invalid XML: encountered a '%s' tag not enclosed within a '%s' tag",
                            TEST_TAG, TEST_PACKAGE_TAG));
                } else if (methodName == null) {
                    Log.e(LOG_TAG, String.format("Invalid XML: missing 'name' attribute for '%s'",
                            TEST_TAG));
                } else {
                    // build class name from package segments
                    StringBuilder classNameBuilder = new StringBuilder();
                    for (Iterator<String> iter = mClassNameStack.iterator(); iter.hasNext(); ) {
                        classNameBuilder.append(iter.next());
                        if (iter.hasNext()) {
                            classNameBuilder.append(".");
                        }
                    }
                    mTestId = new TestIdentifier(classNameBuilder.toString(), methodName);
                    int timeout = -1;
                    String timeoutStr = attributes.getValue("timeout");
                    if (timeoutStr != null) {
                        timeout = Integer.parseInt(timeoutStr);
                    }
                    boolean isKnownFailure = "failure".equals(attributes.getValue("expectation"));
                    if (!isKnownFailure || mIncludeKnownFailures) {
                        String abiList = attributes.getValue("abis");
                        Set<String> abis = new HashSet<String>();
                        if (abiList == null) {
                            // If no specification, add all supported abis
                            abis.addAll(AbiUtils.getAbisSupportedByCts());
                        } else {
                            for (String abi : abiList.split(",")) {
                                // Else only add the abi which are supported
                                abis.add(abi.trim());
                            }
                        }
                        for (String abi : abis) {
                            mPackageDefs.get(abi).addTest(mTestId, timeout);
                        }
                    }
                }
            } else if (TEST_INSTANCE_TAG.equals(localName)) {
                if (mTestId != null) {
                    final Map<String, String> instanceArguments = genAttributeMap(attributes);
                    for (TestPackageDef packageDef : mPackageDefs.values()) {
                        if (packageDef.getTests().contains(mTestId)) {
                            packageDef.addTestInstance(mTestId, instanceArguments);
                        }
                    }
                } else {
                    Log.e(LOG_TAG, String.format(
                            "Invalid XML: encountered a '%s' tag not enclosed within a '%s' tag",
                            TEST_INSTANCE_TAG, TEST_TAG));
                }
            }
        }

        private String getTestType(Attributes attributes) {
            if (parseBoolean(attributes.getValue("hostSideOnly"))) {
                return TestPackageDef.HOST_SIDE_ONLY_TEST;
            } else if (parseBoolean(attributes.getValue("vmHostTest"))) {
                return TestPackageDef.VM_HOST_TEST;
            } else {
                return attributes.getValue("testType");
            }
        }

        @Override
        public void endElement (String uri, String localName, String qName) {
            if (TEST_SUITE_TAG.equals(localName) || TEST_CASE_TAG.equals(localName)) {
                mClassNameStack.pop();
            } else if (TEST_TAG.equals(localName)) {
                mTestId = null;
            }
        }

        /**
         * Parse a boolean attribute value
         */
        private boolean parseBoolean(final String stringValue) {
            return stringValue != null &&
                    Boolean.parseBoolean(stringValue);
        }

        private Map<String, String> genAttributeMap(Attributes attributes) {
            final Map<String, String> attribMap = new HashMap<String, String>();
            for (int i = 0; i < attributes.getLength(); ++i) {
                final String localName = attributes.getLocalName(i);
                final String namespace = attributes.getURI(i);
                final String fullyQualifiedName =
                        (namespace.isEmpty()) ? (localName) : (namespace + ":" + localName);

                attribMap.put(fullyQualifiedName, attributes.getValue(i));
            }
            return attribMap;
        }
    }

    @Override
    protected DefaultHandler createXmlHandler() {
        return new TestPackageHandler();
    }

    /**
     * @return the set of {@link TestPackageDef} containing data parsed from xml
     */
    public Set<TestPackageDef> getTestPackageDefs() {
        return new HashSet<>(mPackageDefs.values());
    }
}
