#
# Copyright (C) 2015 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.
#
from __future__ import absolute_import
from __future__ import print_function

import distutils.spawn
import fnmatch
import imp
import logging
import multiprocessing
import os
import random
import re
import shutil
import subprocess
import sys
import traceback
import xml.etree.ElementTree

import build.lib.build_support
import ndk.abis
import ndk.ansi
import ndk.subprocess
import ndk.test.report
from ndk.test.result import (Success, Failure, Skipped, ExpectedFailure,
                             UnexpectedSuccess)
import ndk.test.spec
import ndk.test.ui
import ndk.test.builder
import tests.filters as filters
import tests.ndk as ndkbuild
import tests.util as util

# pylint: disable=no-self-use


ALL_SUITES = (
    'build',
    'device',
    'libc++',
)


def logger():
    """Return the logger for this module."""
    return logging.getLogger(__name__)


def _get_jobs_args():
    cpus = multiprocessing.cpu_count()
    return ['-j{}'.format(cpus), '-l{}'.format(cpus)]


class TestScanner(object):
    """Creates a Test objects for a given test directory.

    A test scanner is used to turn a test directory into a list of Tests for
    any of the test types found in the directory.
    """
    def find_tests(self, path, name):
        """Searches a directory for tests.

        Args:
            path: Path to the test directory.
            name: Name of the test.

        Returns: List of Tests, possibly empty.
        """
        raise NotImplementedError


class BuildTestScanner(TestScanner):
    def __init__(self, dist=True):
        self.dist = dist
        self.build_configurations = set()

    def add_build_configuration(self, abi, api, toolchain, force_pie, verbose):
        self.build_configurations.add(ndk.test.spec.BuildConfiguration(
            abi, api, toolchain, force_pie, verbose))

    def find_tests(self, path, name):
        # If we have a build.sh, that takes precedence over the Android.mk.
        build_sh_path = os.path.join(path, 'build.sh')
        if os.path.exists(build_sh_path):
            return self.make_build_sh_tests(path, name)

        # Same for test.py
        build_sh_path = os.path.join(path, 'test.py')
        if os.path.exists(build_sh_path):
            return self.make_test_py_tests(path, name)

        # But we can have both ndk-build and cmake tests in the same directory.
        tests = []
        android_mk_path = os.path.join(path, 'jni/Android.mk')
        if os.path.exists(android_mk_path):
            tests.extend(self.make_ndk_build_tests(path, name))

        cmake_lists_path = os.path.join(path, 'CMakeLists.txt')
        if os.path.exists(cmake_lists_path):
            tests.extend(self.make_cmake_tests(path, name))
        return tests

    def make_build_sh_tests(self, path, name):
        tests = []
        for config in self.build_configurations:
            tests.append(ShellBuildTest(name, path, config))
        return tests

    def make_test_py_tests(self, path, name):
        tests = []
        for config in self.build_configurations:
            tests.append(PythonBuildTest(name, path, config))
        return tests

    def make_ndk_build_tests(self, path, name):
        tests = []
        for config in self.build_configurations:
            tests.append(NdkBuildTest(name, path, config, self.dist))
        return tests

    def make_cmake_tests(self, path, name):
        tests = []
        for config in self.build_configurations:
            tests.append(CMakeBuildTest(name, path, config, self.dist))
        return tests


class LibcxxTestScanner(TestScanner):
    ALL_TESTS = []

    def __init__(self, ndk_path):
        self.build_configurations = set()
        LibcxxTestScanner.find_all_libcxx_tests(ndk_path)

    def add_build_configuration(self, abi, api, toolchain, force_pie, verbose):
        self.build_configurations.add(ndk.test.spec.BuildConfiguration(
            abi, api, toolchain, force_pie, verbose))

    def find_tests(self, path, name):
        tests = []
        for config in self.build_configurations:
            tests.append(LibcxxTest('libc++', path, config))
        return tests

    @classmethod
    def find_all_libcxx_tests(cls, ndk_path):
        # If we instantiate multiple LibcxxTestScanners, we still only need to
        # initialize this once. We only create these in the main thread, so
        # there's no risk of race.
        if len(cls.ALL_TESTS) != 0:
            return

        test_base_dir = os.path.join(
            ndk_path, 'sources/cxx-stl/llvm-libc++/test')

        for root, _dirs, files in os.walk(test_base_dir):
            for test_file in files:
                if test_file.endswith('.cpp'):
                    test_path = os.path.relpath(
                        os.path.join(root, test_file), test_base_dir)
                    cls.ALL_TESTS.append(test_path)


def _fixup_expected_failure(result, config, bug):
    if isinstance(result, Failure):
        return ExpectedFailure(result.test, config, bug)
    elif isinstance(result, Success):
        return UnexpectedSuccess(result.test, config, bug)
    else:  # Skipped, UnexpectedSuccess, or ExpectedFailure.
        return result


def _fixup_negative_test(result):
    if isinstance(result, Failure):
        return Success(result.test)
    elif isinstance(result, Success):
        return Failure(result.test, 'negative test case succeeded')
    else:  # Skipped, UnexpectedSuccess, or ExpectedFailure.
        return result


def _run_test(worker, suite, test, obj_dir, dist_dir, test_filters):
    """Runs a given test according to the given filters.

    Args:
        worker: The worker that invoked this task.
        suite: Name of the test suite the test belongs to.
        test: The test to be run.
        obj_dir: Out directory for intermediate build artifacts.
        dist_dir: Out directory for build artifacts needed for running.
        test_filters: Filters to apply when running tests.

    Returns: Tuple of (suite, TestResult, [Test]). The [Test] element is a list
             of additional tests to be run.
    """
    worker.status = 'Building {}'.format(test)

    config = test.check_unsupported()
    if config is not None:
        message = 'test unsupported for {}'.format(config)
        return suite, Skipped(test, message), []

    try:
        result, additional_tests = test.run(obj_dir, dist_dir, test_filters)
        if test.is_negative_test():
            result = _fixup_negative_test(result)
        config, bug = test.check_broken()
        if config is not None:
            # We need to check change each pass/fail to either an
            # ExpectedFailure or an UnexpectedSuccess as necessary.
            result = _fixup_expected_failure(result, config, bug)
    except Exception:  # pylint: disable=broad-except
        result = Failure(test, traceback.format_exc())
        additional_tests = []
    return suite, result, additional_tests


def get_libcxx_test_filter(failing_libcxx_reports):
    """Builds a test filter to rerun only the flaky libc++ test failures.

    We can't rerun each libc++ "test" failure individually because each of them
    is actually just a stub to expose the result from the monolithic LIT test
    run.
    """
    ndk_path = os.environ['NDK']
    test_base_dir = os.path.join(
        ndk_path, 'sources/cxx-stl/llvm-libc++/test')

    libcxx_test_filters = []
    for libcxx_report in failing_libcxx_reports:
        name = libcxx_report.result.test.name
        test_files = find_original_libcxx_test(name)
        if len(test_files) == 0:
            raise RuntimeError('Found no libc++ tests matching ' + name)

        for test_file in test_files:
            logger().info('Found match %s', test_file)
            logger().info(
                'Adding filter %s',
                os.path.relpath(test_file, test_base_dir))
            libcxx_test_filters.append(test_file)

    return filters.TestFilter(libcxx_test_filters)


class TestRunner(object):
    def __init__(self, printer):
        self.printer = printer
        self.tests = {}
        self.build_dirs = {}

    def add_suite(self, name, path, test_scanner):
        if name in self.tests:
            raise KeyError('suite {} already exists'.format(name))
        new_tests = self.scan_test_suite(path, test_scanner)
        self.check_no_overlapping_build_dirs(name, new_tests)
        self.tests[name] = new_tests

    def scan_test_suite(self, suite_dir, test_scanner):
        tests = []
        for dentry in os.listdir(suite_dir):
            path = os.path.join(suite_dir, dentry)
            if os.path.isdir(path):
                test_name = os.path.basename(path)
                tests.extend(test_scanner.find_tests(path, test_name))
        return tests

    def check_no_overlapping_build_dirs(self, suite, new_tests):
        for test in new_tests:
            build_dir = test.get_build_dir('')
            if build_dir in self.build_dirs:
                dup_suite, dup_test = self.build_dirs[build_dir]
                raise RuntimeError(
                    'Found duplicate build directory:\n{} {}\n{} {}'.format(
                        dup_suite, dup_test, suite, test))
            self.build_dirs[build_dir] = (suite, test)

    def run(self, obj_dir, dist_dir, test_filters):
        workqueue = ndk.test.builder.TestBuildWorkQueue()
        try:
            for suite, tests in self.tests.items():
                # Each test configuration was expanded when each test was
                # discovered, so the current order has all the largest tests
                # right next to each other. Spread them out to try to avoid
                # having too many heavy builds happening simultaneously.
                random.shuffle(tests)
                for test in tests:
                    if not test_filters.filter(test.name):
                        continue

                    if test.name == 'libc++':
                        workqueue.add_load_restricted_task(
                            _run_test, suite, test, obj_dir, dist_dir,
                            test_filters)
                    else:
                        workqueue.add_task(
                            _run_test, suite, test, obj_dir, dist_dir,
                            test_filters)

            report = ndk.test.report.Report()
            self.wait_for_results(
                report, workqueue, obj_dir, dist_dir, test_filters)

            return report
        finally:
            workqueue.terminate()
            workqueue.join()

    def wait_for_results(self, report, workqueue, obj_dir, dist_dir,
                         test_filters):
        console = ndk.ansi.get_console()
        ui = ndk.test.ui.get_test_build_progress_ui(console, workqueue)
        with ndk.ansi.disable_terminal_echo(sys.stdin):
            with console.cursor_hide_context():
                while not workqueue.finished():
                    suite, result, additional_tests = workqueue.get_result()
                    # Filtered test. Skip them entirely to avoid polluting
                    # --show-all results.
                    if result is None:
                        assert len(additional_tests) == 0
                        ui.draw()
                        continue

                    assert result.passed() or len(additional_tests) == 0
                    for test in additional_tests:
                        workqueue.add_task(
                            _run_test, suite, test, obj_dir, dist_dir,
                            test_filters)
                    if logger().isEnabledFor(logging.INFO):
                        ui.clear()
                        self.printer.print_result(result)
                    elif result.failed():
                        ui.clear()
                        self.printer.print_result(result)
                    report.add_result(suite, result)
                    ui.draw()
                ui.clear()


class Test(object):
    def __init__(self, name, test_dir, config):
        self.name = name
        self.test_dir = test_dir
        self.config = config

    @property
    def is_flaky(self):
        return False

    def get_test_config(self):
        return TestConfig.from_test_dir(self.test_dir)

    def run(self, obj_dir, dist_dir, test_filters):
        raise NotImplementedError

    def __str__(self):
        return '{} [{}]'.format(self.name, self.config)


def _prep_build_dir(src_dir, out_dir):
    if os.path.exists(out_dir):
        shutil.rmtree(out_dir)
    shutil.copytree(src_dir, out_dir)


class TestConfig(object):
    """Describes the status of a test.

    Each test directory can contain a "test_config.py" file that describes
    the configurations a test is not expected to pass for. Previously this
    information could be captured in one of two places: the Application.mk
    file, or a BROKEN_BUILD/BROKEN_RUN file.

    Application.mk was used to state that a test was only to be run for a
    specific platform version, specific toolchain, or a set of ABIs.
    Unfortunately Application.mk could only specify a single toolchain or
    platform, not a set.

    BROKEN_BUILD/BROKEN_RUN files were too general. An empty file meant the
    test should always be skipped regardless of configuration. Any change that
    would put a test in that situation should be reverted immediately. These
    also didn't make it clear if the test was actually broken (and thus should
    be fixed) or just not applicable.

    A test_config.py file is more flexible. It is a Python module that defines
    at least one function by the same name as one in TestConfig.NullTestConfig.
    If a function is not defined the null implementation (not broken,
    supported), will be used.
    """

    class NullTestConfig(object):
        def __init__(self):
            pass

        # pylint: disable=unused-argument
        @staticmethod
        def build_broken(abi, platform, toolchain):
            """Tests if a given configuration is known broken.

            A broken test is a known failing test that should be fixed.

            Any test with a non-empty broken section requires a "bug" entry
            with a link to either an internal bug (http://b/BUG_NUMBER) or a
            public bug (http://b.android.com/BUG_NUMBER).

            These tests will still be built and run. If the test succeeds, it
            will be reported as an error.

            Returns: A tuple of (broken_configuration, bug) or (None, None).
            """
            return None, None

        @staticmethod
        def build_unsupported(abi, platform, toolchain):
            """Tests if a given configuration is unsupported.

            An unsupported test is a test that do not make sense to run for a
            given configuration. Testing x86 assembler on MIPS, for example.

            These tests will not be built or run.

            Returns: The string unsupported_configuration or None.
            """
            return None

        @staticmethod
        def extra_cmake_flags():
            return []

        @staticmethod
        def extra_ndk_build_flags():
            """Returns extra flags that should be passed to ndk-build."""
            return []

        @staticmethod
        def is_negative_test():
            """Returns True if this test should pass if the build fails.

            Note that this is different from build_broken. Use build_broken to
            indicate a bug and use is_negative_test to indicate a test that
            should fail if things are working.

            Also note that check_broken and is_negative_test can be layered. If
            a build is expected to fail, but doesn't for armeabi, the
            test_config could contain:

                def is_negative_test():
                    return True


                def build_broken(abi, api, toolchain):
                    if abi == 'armeabi':
                        return abi, bug_url
                    return None, None
            """
            return False
        # pylint: enable=unused-argument

    def __init__(self, file_path):
        # Note that this namespace isn't actually meaningful from our side;
        # it's only what the loaded module's __name__ gets set to.
        dirname = os.path.dirname(file_path)
        namespace = '.'.join([dirname, 'test_config'])

        try:
            self.module = imp.load_source(namespace, file_path)
        except IOError:
            self.module = None

        try:
            self.build_broken = self.module.build_broken
        except AttributeError:
            self.build_broken = self.NullTestConfig.build_broken

        try:
            self.build_unsupported = self.module.build_unsupported
        except AttributeError:
            self.build_unsupported = self.NullTestConfig.build_unsupported

        try:
            self.extra_cmake_flags = self.module.extra_cmake_flags
        except AttributeError:
            self.extra_cmake_flags = self.NullTestConfig.extra_cmake_flags

        try:
            self.extra_ndk_build_flags = self.module.extra_ndk_build_flags
        except AttributeError:
            ntc = self.NullTestConfig
            self.extra_ndk_build_flags = ntc.extra_ndk_build_flags

        try:
            self.is_negative_test = self.module.is_negative_test
        except AttributeError:
            self.is_negative_test = self.NullTestConfig.is_negative_test

    @classmethod
    def from_test_dir(cls, test_dir):
        path = os.path.join(test_dir, 'test_config.py')
        return cls(path)


class DeviceTestConfig(TestConfig):
    """Specialization of test_config.py that includes device API level.

    We need to mark some tests as broken or unsupported based on what device
    they are running on, as opposed to just what they were built for.
    """
    class NullTestConfig(TestConfig.NullTestConfig):
        # pylint: disable=unused-argument
        @staticmethod
        def run_broken(abi, device_api, toolchain, subtest):
            return None, None

        @staticmethod
        def run_unsupported(abi, device_api, toolchain, subtest):
            return None

        @staticmethod
        def extra_cmake_flags():
            return []
        # pylint: enable=unused-argument

    def __init__(self, file_path):
        super(DeviceTestConfig, self).__init__(file_path)

        try:
            self.run_broken = self.module.run_broken
        except AttributeError:
            self.run_broken = self.NullTestConfig.run_broken

        try:
            self.run_unsupported = self.module.run_unsupported
        except AttributeError:
            self.run_unsupported = self.NullTestConfig.run_unsupported

        try:
            _ = self.module.is_negative_test
            # If the build is expected to fail, then it should just be a build
            # test since the test should never be run.
            #
            # If the run is expected to fail, just fix the test to pass for
            # thatr case. Gtest death tests can handle the more complicated
            # cases.
            raise RuntimeError('is_negative_test is invalid for device tests')
        except AttributeError:
            pass


def _run_build_sh_test(test, build_dir, test_dir, ndk_build_flags, abi,
                       platform, toolchain):
    _prep_build_dir(test_dir, build_dir)
    with util.cd(build_dir):
        build_cmd = ['bash', 'build.sh'] + _get_jobs_args() + ndk_build_flags
        test_env = dict(os.environ)
        if abi is not None:
            test_env['APP_ABI'] = abi
        test_env['APP_PLATFORM'] = 'android-{}'.format(platform)
        assert toolchain is not None
        test_env['NDK_TOOLCHAIN_VERSION'] = toolchain
        rc, out = ndk.subprocess.call_output(build_cmd, env=test_env)
        if rc == 0:
            return Success(test)
        else:
            return Failure(test, out)


def _run_ndk_build_test(test, obj_dir, dist_dir, test_dir, ndk_build_flags,
                        abi, platform, toolchain):
    _prep_build_dir(test_dir, obj_dir)
    with util.cd(obj_dir):
        args = [
            'APP_ABI=' + abi,
            'NDK_TOOLCHAIN_VERSION=' + toolchain,
            'NDK_LIBS_OUT=' + dist_dir,
        ]
        args.extend(_get_jobs_args())
        if platform is not None:
            args.append('APP_PLATFORM=android-{}'.format(platform))
        rc, out = ndkbuild.build(args + ndk_build_flags)
        if rc == 0:
            return Success(test)
        else:
            return Failure(test, out)


def _run_cmake_build_test(test, obj_dir, dist_dir, test_dir, cmake_flags, abi,
                          platform, toolchain):
    _prep_build_dir(test_dir, obj_dir)

    # Add prebuilts to PATH.
    prebuilts_host_tag = build.lib.build_support.get_default_host() + '-x86'
    prebuilts_bin = build.lib.build_support.android_path(
        'prebuilts', 'cmake', prebuilts_host_tag, 'bin')
    env = dict(os.environ)
    env['PATH'] = prebuilts_bin + os.pathsep + os.environ['PATH']

    # Skip if we don't have a working cmake executable, either from the
    # prebuilts, or from the SDK, or if a new enough version is installed.
    if distutils.spawn.find_executable('cmake') is None:
        return Skipped(test, 'cmake executable not found')
    out = subprocess.check_output(['cmake', '--version'], env=env)
    version_pattern = r'cmake version (\d+)\.(\d+)\.'
    version = [int(v) for v in re.match(version_pattern, out).groups()]
    if version < [3, 6]:
        return Skipped(test, 'cmake 3.6 or above required')

    toolchain_file = os.path.join(os.environ['NDK'], 'build', 'cmake',
                                  'android.toolchain.cmake')
    objs_dir = os.path.join(obj_dir, abi)
    libs_dir = os.path.join(dist_dir, abi)
    if toolchain != 'clang':
        toolchain = 'gcc'
    args = [
        '-H' + obj_dir,
        '-B' + objs_dir,
        '-DCMAKE_TOOLCHAIN_FILE=' + toolchain_file,
        '-DANDROID_ABI=' + abi,
        '-DANDROID_TOOLCHAIN=' + toolchain,
        '-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=' + libs_dir,
        '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + libs_dir
    ]
    rc, _ = ndk.subprocess.call_output(['ninja', '--version'], env=env)
    if rc == 0:
        args += [
            '-GNinja',
            '-DCMAKE_MAKE_PROGRAM=ninja',
        ]
    if platform is not None:
        args.append('-DANDROID_PLATFORM=android-{}'.format(platform))
    rc, out = ndk.subprocess.call_output(
        ['cmake'] + cmake_flags + args, env=env)
    if rc != 0:
        return Failure(test, out)
    rc, out = ndk.subprocess.call_output(
        ['cmake', '--build', objs_dir, '--'] + _get_jobs_args(), env=env)
    if rc != 0:
        return Failure(test, out)
    return Success(test)


class BuildTest(Test):
    def __init__(self, name, test_dir, config):
        super(BuildTest, self).__init__(name, test_dir, config)

        if self.api is None:
            raise ValueError

    @property
    def abi(self):
        return self.config.abi

    @property
    def api(self):
        return self.config.api

    @property
    def platform(self):
        return self.api

    @property
    def toolchain(self):
        return self.config.toolchain

    @property
    def ndk_build_flags(self):
        flags = self.config.get_extra_ndk_build_flags()
        if flags is None:
            flags = []
        return flags + self.get_extra_ndk_build_flags()

    @property
    def cmake_flags(self):
        flags = self.config.get_extra_cmake_flags()
        if flags is None:
            flags = []
        return flags + self.get_extra_cmake_flags()

    def run(self, obj_dir, dist_dir, _test_filters):
        raise NotImplementedError

    def check_broken(self):
        return self.get_test_config().build_broken(
            self.abi, self.platform, self.toolchain)

    def check_unsupported(self):
        return self.get_test_config().build_unsupported(
            self.abi, self.platform, self.toolchain)

    def is_negative_test(self):
        return self.get_test_config().is_negative_test()

    def get_extra_cmake_flags(self):
        return self.get_test_config().extra_cmake_flags()

    def get_extra_ndk_build_flags(self):
        return self.get_test_config().extra_ndk_build_flags()


class PythonBuildTest(BuildTest):
    """A test that is implemented by test.py.

    A test.py test has a test.py file in its root directory. This module
    contains a run_test function which returns a tuple of `(boolean_success,
    string_failure_message)` and takes the following kwargs (all of which
    default to None):

    abi: ABI to test as a string.
    platform: Platform to build against as a string.
    toolchain: Toolchain to use as a string.
    ndk_build_flags: Additional build flags that should be passed to ndk-build
                     if invoked as a list of strings.
    """
    def __init__(self, name, test_dir, config):
        api = config.api
        if api is None:
            api = build.lib.build_support.minimum_platform_level(config.abi)
        config = ndk.test.spec.BuildConfiguration(
            config.abi, api, config.toolchain, config.force_pie,
            config.verbose)
        super(PythonBuildTest, self).__init__(name, test_dir, config)

        if self.abi not in build.lib.build_support.ALL_ABIS:
            raise ValueError('{} is not a valid ABI'.format(self.abi))

        try:
            int(self.platform)
        except ValueError:
            raise ValueError(
                '{} is not a valid platform number'.format(self.platform))

        if self.toolchain != 'clang' and self.toolchain != '4.9':
            raise ValueError(
                '{} is not a valid toolchain name'.format(self.toolchain))

        # Not a ValueError for this one because it should be impossible. This
        # is actually a computed result from the config we're passed.
        assert self.ndk_build_flags is not None

    def get_build_dir(self, out_dir):
        return os.path.join(out_dir, str(self.config), 'test.py', self.name)

    def run(self, obj_dir, _dist_dir, _test_filters):
        build_dir = self.get_build_dir(obj_dir)
        logger().info('Building test: %s', self.name)
        _prep_build_dir(self.test_dir, build_dir)
        with util.cd(build_dir):
            module = imp.load_source('test', 'test.py')
            success, failure_message = module.run_test(
                self.abi, self.platform, self.toolchain, self.ndk_build_flags)
            if success:
                return Success(self), []
            else:
                return Failure(self, failure_message), []


class ShellBuildTest(BuildTest):
    def __init__(self, name, test_dir, config):
        api = config.api
        if api is None:
            api = build.lib.build_support.minimum_platform_level(config.abi)
        config = ndk.test.spec.BuildConfiguration(
            config.abi, api, config.toolchain, config.force_pie,
            config.verbose)
        super(ShellBuildTest, self).__init__(name, test_dir, config)

    def get_build_dir(self, out_dir):
        return os.path.join(out_dir, str(self.config), 'build.sh', self.name)

    def run(self, obj_dir, _dist_dir, _test_filters):
        build_dir = self.get_build_dir(obj_dir)
        logger().info('Building test: %s', self.name)
        if os.name == 'nt':
            reason = 'build.sh tests are not supported on Windows'
            return Skipped(self, reason), []
        else:
            result = _run_build_sh_test(
                self, build_dir, self.test_dir, self.ndk_build_flags,
                self.abi, self.platform, self.toolchain)
            return result, []


def _platform_from_application_mk(test_dir):
    """Determine target API level from a test's Application.mk.

    Args:
        test_dir: Directory of the test to read.

    Returns:
        Integer portion of APP_PLATFORM if found, else None.

    Raises:
        ValueError: Found an unexpected value for APP_PLATFORM.
    """
    application_mk = os.path.join(test_dir, 'jni/Application.mk')
    if not os.path.exists(application_mk):
        return None

    with open(application_mk) as application_mk_file:
        for line in application_mk_file:
            if line.startswith('APP_PLATFORM'):
                _, platform_str = line.split(':=')
                break
        else:
            return None

    platform_str = platform_str.strip()
    if not platform_str.startswith('android-'):
        raise ValueError(platform_str)

    _, api_level_str = platform_str.split('-')
    return int(api_level_str)


def _get_or_infer_app_platform(platform_from_user, test_dir, abi):
    """Determines the platform level to use for a test using ndk-build.

    Choose the platform level from, in order of preference:
    1. Value given as argument.
    2. APP_PLATFORM from jni/Application.mk.
    3. Default value for the target ABI.

    Args:
        platform_from_user: A user provided platform level or None.
        test_dir: The directory containing the ndk-build project.
        abi: The ABI being targeted.

    Returns:
        The platform version the test should build against.
    """
    if platform_from_user is not None:
        return platform_from_user

    minimum_version = build.lib.build_support.minimum_platform_level(abi)
    platform_from_application_mk = _platform_from_application_mk(test_dir)
    if platform_from_application_mk is not None:
        if platform_from_application_mk >= minimum_version:
            return platform_from_application_mk

    return minimum_version


class NdkBuildTest(BuildTest):
    def __init__(self, name, test_dir, config, dist):
        api = _get_or_infer_app_platform(config.api, test_dir, config.abi)
        config = ndk.test.spec.BuildConfiguration(
            config.abi, api, config.toolchain, config.force_pie,
            config.verbose)
        super(NdkBuildTest, self).__init__(name, test_dir, config)
        self.dist = dist

    def get_dist_dir(self, obj_dir, dist_dir):
        if self.dist:
            return self.get_build_dir(dist_dir)
        else:
            return os.path.join(self.get_build_dir(obj_dir), 'dist')

    def get_build_dir(self, out_dir):
        return os.path.join(out_dir, str(self.config), 'ndk-build', self.name)

    def run(self, obj_dir, dist_dir, _test_filters):
        logger().info('Building test: %s', self.name)
        obj_dir = self.get_build_dir(obj_dir)
        dist_dir = self.get_dist_dir(obj_dir, dist_dir)
        result = _run_ndk_build_test(
            self, obj_dir, dist_dir, self.test_dir, self.ndk_build_flags,
            self.abi, self.platform, self.toolchain)
        return result, []


class CMakeBuildTest(BuildTest):
    def __init__(self, name, test_dir, config, dist):
        api = _get_or_infer_app_platform(config.api, test_dir, config.abi)
        config = ndk.test.spec.BuildConfiguration(
            config.abi, api, config.toolchain, config.force_pie,
            config.verbose)
        super(CMakeBuildTest, self).__init__(name, test_dir, config)
        self.dist = dist

    def get_dist_dir(self, obj_dir, dist_dir):
        if self.dist:
            return self.get_build_dir(dist_dir)
        else:
            return os.path.join(self.get_build_dir(obj_dir), 'dist')

    def get_build_dir(self, out_dir):
        return os.path.join(out_dir, str(self.config), 'cmake', self.name)

    def run(self, obj_dir, dist_dir, _test_filters):
        obj_dir = self.get_build_dir(obj_dir)
        dist_dir = self.get_dist_dir(obj_dir, dist_dir)
        logger().info('Building test: %s', self.name)
        result = _run_cmake_build_test(
            self, obj_dir, dist_dir, self.test_dir, self.cmake_flags, self.abi,
            self.platform, self.toolchain)
        return result, []


def get_xunit_reports(xunit_file, config):
    tree = xml.etree.ElementTree.parse(xunit_file)
    root = tree.getroot()
    cases = root.findall('.//testcase')

    reports = []
    for test_case in cases:
        mangled_test_dir = test_case.get('classname')

        # The classname is the path from the root of the libc++ test directory
        # to the directory containing the test (prefixed with 'libc++.')...
        mangled_path = '/'.join([mangled_test_dir, test_case.get('name')])

        # ... that has had '.' in its path replaced with '_' because xunit.
        test_matches = find_original_libcxx_test(mangled_path)
        if len(test_matches) == 0:
            raise RuntimeError('Found no matches for test ' + mangled_path)
        if len(test_matches) > 1:
            raise RuntimeError('Found multiple matches for test {}: {}'.format(
                mangled_path, test_matches))
        assert len(test_matches) == 1

        # We found a unique path matching the xunit class/test name.
        name = test_matches[0]
        test_dir = os.path.dirname(name)[len('libc++.'):]

        failure_nodes = test_case.findall('failure')
        if len(failure_nodes) == 0:
            reports.append(XunitSuccess(name, test_dir, config))
            continue

        if len(failure_nodes) != 1:
            msg = ('Could not parse XUnit output: test case does not have a '
                   'unique failure node: {}'.format(name))
            raise RuntimeError(msg)

        failure_node = failure_nodes[0]
        failure_text = failure_node.text
        reports.append(XunitFailure(name, test_dir, failure_text, config))
    return reports


class LibcxxTest(Test):
    def __init__(self, name, test_dir, config):
        if config.api is None:
            config.api = ndk.abis.min_api_for_abi(config.abi)

        super(LibcxxTest, self).__init__(name, test_dir, config)

    @property
    def abi(self):
        return self.config.abi

    @property
    def api(self):
        return self.config.api

    @property
    def toolchain(self):
        return self.config.toolchain

    def get_build_dir(self, out_dir):
        return os.path.join(out_dir, str(self.config), 'libcxx', self.name)

    def run(self, obj_dir, dist_dir, test_filters):
        build_dir = self.get_build_dir(dist_dir)

        if not os.path.exists(build_dir):
            os.makedirs(build_dir)

        xunit_output = os.path.join(build_dir, 'xunit.xml')
        ndk_path = os.environ['NDK']
        libcxx_subpath = 'sources/cxx-stl/llvm-libc++'
        libcxx_path = os.path.join(ndk_path, libcxx_subpath)
        libcxx_so_path = os.path.join(
            libcxx_path, 'libs', self.config.abi, 'libc++_shared.so')
        libcxx_test_path = os.path.join(libcxx_path, 'test')
        shutil.copy2(libcxx_so_path, build_dir)

        cmd = [
            'python', 'test_libcxx.py',
            '--abi', self.abi,
            '--platform', str(self.api),
            '--xunit-xml-output=' + xunit_output,
            '--timeout=600',
            '--ndk=' + ndk_path,

            # We don't want the progress bar since we're already printing our
            # own output, so we need --show-all so we get *some* output,
            # otherwise it would just be quiet for several minutes and it
            # wouldn't be clear if something had hung.
            '--no-progress-bar',
            '--show-all',
            '--build-only',

            '--out-dir', build_dir,
        ]

        if self.config.force_pie or self.abi in ndk.abis.LP64_ABIS:
            cmd.append('--pie')

        # The libc++ test runner's filters are path based. Assemble the path to
        # the test based on the late_filters (early filters for a libc++ test
        # would be simply "libc++", so that's not interesting at this stage).
        for late_filter in test_filters.late_filters:
            filter_pattern = late_filter.pattern
            if not filter_pattern.startswith('libc++.'):
                continue

            _, _, path = filter_pattern.partition('.')
            if not os.path.isabs(path):
                path = os.path.join(libcxx_test_path, path)

            # If we have a filter like "libc++.std", we'll run everything in
            # std, but all our XunitReport "tests" will be filtered out.  Make
            # sure we have something usable.
            if path.endswith('*'):
                # But the libc++ test runner won't like that, so strip it.
                path = path[:-1]
            else:
                assert os.path.isfile(path)

            cmd.append(path)

        # Ignore the exit code. We do most XFAIL processing outside the test
        # runner so expected failures in the test runner will still cause a
        # non-zero exit status. This "test" only fails if we encounter a Python
        # exception. Exceptions raised from our code are already caught by the
        # test runner. If that happens in test_libcxx.py or in LIT, the xunit
        # output will not be valid and we'll fail get_xunit_reports and raise
        # an exception anyway.
        with open('/dev/null', 'w') as dev_null:
            stdout = dev_null
            stderr = dev_null
            if logger().isEnabledFor(logging.INFO):
                stdout = None
                stderr = None
            subprocess.call(cmd, stdout=stdout, stderr=stderr)

        for root, _, files in os.walk(libcxx_test_path):
            for test_file in files:
                if not test_file.endswith('.dat'):
                    continue
                test_relpath = os.path.relpath(root, libcxx_test_path)
                dest_dir = os.path.join(build_dir, test_relpath)
                if not os.path.exists(dest_dir):
                    continue

                shutil.copy2(os.path.join(root, test_file), dest_dir)

        # We create a bunch of fake tests that report the status of each
        # individual test in the xunit report.
        test_reports = get_xunit_reports(xunit_output, self.config)

        return Success(self), test_reports

    def check_broken(self):
        # Actual results are reported individually by pulling them out of the
        # xunit output. This just reports the status of the overall test run,
        # which should be passing.
        return None, None

    def check_unsupported(self):
        # The NDK's libc++ support has always come with a big scary beta label
        # on it. The tests have never been 100% passing. We're going to only
        # enable it for a handful of configurations as support falls in to
        # place.
        if self.toolchain == '4.9':
            return '4.9'

        supported_abis = (
            'arm64-v8a',
            'armeabi-v7a',
            'x86',
            'x86_64',
        )

        if self.abi not in supported_abis:
            # The ABI case is something we will eventually support, but don't
            # bother wasting time running them until we get to that point.
            return self.abi

        return None

    def is_negative_test(self):
        return False


class LibcxxTestConfig(DeviceTestConfig):
    """Specialization of test_config.py for libc++.

    The libc++ tests have multiple tests in a single directory, so we need to
    pass the test name for build_broken too.
    """
    class NullTestConfig(TestConfig.NullTestConfig):
        # pylint: disable=unused-argument,arguments-differ
        @staticmethod
        def build_unsupported(abi, api, toolchain, name):
            return None

        @staticmethod
        def build_broken(abi, api, toolchain, name):
            return None, None

        @staticmethod
        def run_unsupported(abi, device_api, toolchain, name):
            return None

        @staticmethod
        def run_broken(abi, device_api, toolchain, name):
            return None, None
        # pylint: enable=unused-argument,arguments-differ


def find_original_libcxx_test(name):
    """Finds the original libc++ test file given the xunit test name.

    LIT mangles test names to replace all periods with underscores because
    xunit. This returns all tests that could possibly match the xunit test
    name.
    """

    # LIT special cases tests in the root of the test directory (such as
    # test/nothing_to_do.pass.cpp) as "libc++.libc++/$TEST_FILE.pass.cpp" for
    # some reason. Strip it off so we can find the tests.
    if name.startswith('libc++.libc++/'):
        name = 'libc++.' + name[len('libc++.libc++/'):]

    test_prefix = 'libc++.'
    if not name.startswith(test_prefix):
        raise ValueError('libc++ test name must begin with "libc++."')

    name = name[len(test_prefix):]
    test_pattern = name.replace('_', '?')
    matches = []
    for match in fnmatch.filter(LibcxxTestScanner.ALL_TESTS, test_pattern):
        matches.append(test_prefix + match)
    return matches


class XunitResult(Test):
    """Fake tests so we can show a result for each libc++ test.

    We create these by parsing the xunit XML output from the libc++ test
    runner. For each result, we create an XunitResult "test" that simply
    returns a result for the xunit status.

    We don't have an ExpectedFailure form of the XunitResult because that is
    already handled for us by the libc++ test runner.
    """
    def __init__(self, name, test_dir, config):
        super(XunitResult, self).__init__(name, test_dir, config)

    def run(self, _out_dir, _dist_dir, _test_filters):
        raise NotImplementedError

    @property
    def is_flaky(self):
        return True

    def get_test_config(self):
        test_config_dir = build.lib.build_support.ndk_path(
            'tests/libc++/test', self.test_dir)
        return LibcxxTestConfig.from_test_dir(test_config_dir)

    def check_broken(self):
        name = os.path.splitext(os.path.basename(self.name))[0]
        config, bug = self.get_test_config().build_broken(
            self.config.abi, self.config.api, self.config.toolchain, name)
        if config is not None:
            return config, bug
        return None, None

    def check_unsupported(self):
        return None

    def is_negative_test(self):
        return False


class XunitSuccess(XunitResult):
    def run(self, _out_dir, _dist_dir, _test_filters):
        return Success(self), []


class XunitFailure(XunitResult):
    def __init__(self, name, test_dir, text, config):
        super(XunitFailure, self).__init__(name, test_dir, config)
        self.text = text

    def run(self, _out_dir, _dist_dir, _test_filters):
        return Failure(self, self.text), []
