# Copyright 2019 The Pigweed Authors
#
# 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
#
#     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.
"""Runs Pigweed unit tests built using GN."""

import argparse
import asyncio
import base64
import enum
import json
import logging
import os
import re
import subprocess
import sys
import time

from pathlib import Path
from typing import Dict, Iterable, List, Optional, Sequence, Set, Tuple

import requests

import pw_cli.log
import pw_cli.process

# Global logger for the script.
_LOG: logging.Logger = logging.getLogger(__name__)

_ANSI_SEQUENCE_REGEX = re.compile(rb'\x1b[^m]*m')


def _strip_ansi(bytes_with_sequences: bytes) -> bytes:
    """Strip out ANSI escape sequences."""
    return _ANSI_SEQUENCE_REGEX.sub(b'', bytes_with_sequences)


def register_arguments(parser: argparse.ArgumentParser) -> None:
    """Registers command-line arguments."""

    parser.add_argument('--root',
                        type=str,
                        default='out',
                        help='Path to the root build directory')
    parser.add_argument('-r',
                        '--runner',
                        type=str,
                        required=True,
                        help='Executable which runs a test on the target')
    parser.add_argument('-m',
                        '--timeout',
                        type=float,
                        help='Timeout for test runner in seconds')
    parser.add_argument('runner_args',
                        nargs="*",
                        help='Arguments to forward to the test runner')

    # The runner script can either run binaries directly or groups.
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-g',
                       '--group',
                       action='append',
                       help='Test groups to run')
    group.add_argument('-t',
                       '--test',
                       action='append',
                       help='Test binaries to run')


class TestResult(enum.Enum):
    """Result of a single unit test run."""
    UNKNOWN = 0
    SUCCESS = 1
    FAILURE = 2


class Test:
    """A unit test executable."""
    def __init__(self, name: str, file_path: str) -> None:
        self.name: str = name
        self.file_path: str = file_path
        self.status: TestResult = TestResult.UNKNOWN
        self.duration_s: float

    def __repr__(self) -> str:
        return f'Test({self.name})'

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, Test):
            return NotImplemented
        return self.file_path == other.file_path

    def __hash__(self) -> int:
        return hash(self.file_path)


class TestGroup:
    """Graph node representing a group of unit tests."""
    def __init__(self, name: str, tests: Iterable[Test]):
        self._name: str = name
        self._deps: Iterable['TestGroup'] = []
        self._tests: Iterable[Test] = tests

    def set_deps(self, deps: Iterable['TestGroup']) -> None:
        """Updates the dependency list of this group."""
        self._deps = deps

    def all_test_dependencies(self) -> List[Test]:
        """Returns a list of all tests in this group and its dependencies."""
        return list(self._all_test_dependencies(set()))

    def _all_test_dependencies(self, processed_groups: Set[str]) -> Set[Test]:
        if self._name in processed_groups:
            return set()

        tests: Set[Test] = set()
        for dep in self._deps:
            tests.update(
                dep._all_test_dependencies(  # pylint: disable=protected-access
                    processed_groups))

        tests.update(self._tests)
        processed_groups.add(self._name)

        return tests

    def __repr__(self) -> str:
        return f'TestGroup({self._name})'


class TestRunner:
    """Runs unit tests by calling out to a runner script."""
    def __init__(self,
                 executable: str,
                 args: Sequence[str],
                 tests: Iterable[Test],
                 timeout: Optional[float] = None) -> None:
        self._executable: str = executable
        self._args: Sequence[str] = args
        self._tests: List[Test] = list(tests)
        self._timeout = timeout

        # Access go/result-sink, if available.
        ctx_path = Path(os.environ.get("LUCI_CONTEXT", ''))
        if not ctx_path.is_file():
            return

        ctx = json.loads(ctx_path.read_text(encoding='utf-8'))
        self._result_sink: Optional[Dict[str,
                                         str]] = ctx.get('result_sink', None)

    async def run_tests(self) -> None:
        """Runs all registered unit tests through the runner script."""

        for idx, test in enumerate(self._tests, 1):
            total = str(len(self._tests))
            test_counter = f'Test {idx:{len(total)}}/{total}'

            _LOG.info('%s: [ RUN] %s', test_counter, test.name)

            # Convert POSIX to native directory seperators as GN produces '/'
            # but the Windows test runner needs '\\'.
            command = [
                str(Path(self._executable)),
                str(Path(test.file_path)), *self._args
            ]

            if self._executable.endswith('.py'):
                command.insert(0, sys.executable)

            start_time = time.monotonic()
            try:
                process = await pw_cli.process.run_async(*command,
                                                         timeout=self._timeout)
            except subprocess.CalledProcessError as err:
                _LOG.error(err)
                return
            test.duration_s = time.monotonic() - start_time

            if process.returncode == 0:
                test.status = TestResult.SUCCESS
                test_result = 'PASS'
            else:
                test.status = TestResult.FAILURE
                test_result = 'FAIL'

                _LOG.log(pw_cli.log.LOGLEVEL_STDOUT, '[Pid: %s]\n%s',
                         pw_cli.color.colors().bold_white(process.pid),
                         process.output.decode(errors='ignore').rstrip())

                _LOG.info('%s: [%s] %s in %.3f s', test_counter, test_result,
                          test.name, test.duration_s)

            try:
                self._maybe_upload_to_resultdb(test, process)
            except requests.exceptions.HTTPError as err:
                _LOG.error(err)
                return

    def all_passed(self) -> bool:
        """Returns true if all unit tests passed."""
        return all(test.status is TestResult.SUCCESS for test in self._tests)

    def _maybe_upload_to_resultdb(self, test: Test,
                                  process: pw_cli.process.CompletedProcess):
        """Uploads test result to ResultDB, if available."""
        if self._result_sink is None:
            # ResultDB integration not enabled.
            return

        test_result = {
            # The test.name is not suitable as an identifier because it's just
            # the basename of the test (channel_test). We want the full path,
            # including the toolchain used.
            "testId": test.file_path,
            # ResultDB also supports CRASH and ABORT, but there's currently no
            # way to distinguish these in pw_unit_test.
            "status": "PASS" if test.status is TestResult.SUCCESS else "FAIL",
            # The "expected" field is required. It could be used to report
            # expected failures, but we don't currently support these in
            # pw_unit_test.
            "expected": test.status is TestResult.SUCCESS,
            # Ensure to format the duration with '%.9fs' to avoid scientific
            # notation.  If a value is too large or small and formatted with
            # str() or '%s', python formats the value in scientific notation,
            # like '1.1e-10', which is an invalid input for
            # google.protobuf.duration.
            "duration": "%.9fs" % test.duration_s,
            "summaryHtml":
            '<p><text-artifact artifact-id="artifact-content-in-request"></p>',
            "artifacts": {
                "artifact-content-in-request": {
                    # Need to decode the bytes back to ASCII or they will not be
                    # encodable by json.dumps.
                    #
                    # TODO(b/248349219): Instead of stripping the ANSI color
                    # codes, convert them to HTML.
                    "contents":
                    base64.b64encode(_strip_ansi(
                        process.output)).decode('ascii'),
                },
            },
        }

        requests.post(
            url='http://%s/prpc/luci.resultsink.v1.Sink/ReportTestResults' %
            self._result_sink['address'],
            headers={
                'Content-Type': 'application/json',
                'Accept': 'application/json',
                'Authorization':
                'ResultSink %s' % self._result_sink['auth_token'],
            },
            data=json.dumps({'testResults': [test_result]}),
        ).raise_for_status()


# Filename extension for unit test metadata files.
METADATA_EXTENSION = '.testinfo.json'


def find_test_metadata(root: str) -> List[str]:
    """Locates all test metadata files located within a directory tree."""

    metadata: List[str] = []
    for path, _, files in os.walk(root):
        for filename in files:
            if not filename.endswith(METADATA_EXTENSION):
                continue

            full_path = os.path.join(path, filename)
            _LOG.debug('Found group metadata at %s', full_path)
            metadata.append(full_path)

    return metadata


# TODO(frolv): This is copied from the Python runner script.
# It should be extracted into a library and imported instead.
def find_binary(target: str) -> str:
    """Tries to find a binary for a gn build target.

    Args:
        target: Relative filesystem path to the target's output directory and
            target name, separated by a colon.

    Returns:
        Full path to the target's binary.

    Raises:
        FileNotFoundError: No binary found for target.
    """

    target_path, target_name = target.split(':')

    for extension in ['', '.elf', '.exe']:
        potential_filename = f'{target_path}/{target_name}{extension}'
        if os.path.isfile(potential_filename):
            return potential_filename

    raise FileNotFoundError(
        f'Could not find output binary for build target {target}')


def parse_metadata(metadata: List[str], root: str) -> Dict[str, TestGroup]:
    """Builds a graph of test group objects from metadata.

    Args:
        metadata: List of paths to JSON test metadata files.
        root: Root output directory of the build.

    Returns:
        Map of group name to TestGroup object. All TestGroup objects are fully
        populated with the paths to their unit tests and references to their
        dependencies.
    """
    def canonicalize(path: str) -> str:
        """Removes a trailing slash from a GN target's directory.

        '//module:target'  -> '//module:target'
        '//module/:target' -> '//module:target'
        """
        index = path.find(':')
        if index == -1 or path[index - 1] != '/':
            return path
        return path[:index - 1] + path[index:]

    group_deps: List[Tuple[str, List[str]]] = []
    all_tests: Dict[str, Test] = {}
    test_groups: Dict[str, TestGroup] = {}
    num_tests = 0

    for path in metadata:
        with open(path, 'r') as metadata_file:
            metadata_list = json.load(metadata_file)

        deps: List[str] = []
        tests: List[Test] = []

        for entry in metadata_list:
            if entry['type'] == 'self':
                group_name = canonicalize(entry['name'])
            elif entry['type'] == 'dep':
                deps.append(canonicalize(entry['group']))
            elif entry['type'] == 'test':
                test_directory = os.path.join(root, entry['test_directory'])
                test_binary = find_binary(
                    f'{test_directory}:{entry["test_name"]}')

                if test_binary not in all_tests:
                    all_tests[test_binary] = Test(entry['test_name'],
                                                  test_binary)

                tests.append(all_tests[test_binary])

        if deps:
            group_deps.append((group_name, deps))

        num_tests += len(tests)
        test_groups[group_name] = TestGroup(group_name, tests)

    for name, deps in group_deps:
        test_groups[name].set_deps([test_groups[dep] for dep in deps])

    _LOG.info('Found %d test groups (%d tests).', len(metadata), num_tests)
    return test_groups


def tests_from_groups(group_names: Optional[Sequence[str]],
                      root: str) -> List[Test]:
    """Returns unit tests belonging to test groups and their dependencies.

    If args.names is nonempty, only searches groups specified there.
    Otherwise, finds tests from all known test groups.
    """

    _LOG.info('Scanning for tests...')
    metadata = find_test_metadata(root)
    test_groups = parse_metadata(metadata, root)

    groups_to_run = group_names if group_names else test_groups.keys()
    tests_to_run: Set[Test] = set()

    for name in groups_to_run:
        try:
            tests_to_run.update(test_groups[name].all_test_dependencies())
        except KeyError:
            _LOG.error('Unknown test group: %s', name)
            sys.exit(1)

    _LOG.info('Running test groups %s', ', '.join(groups_to_run))
    return list(tests_to_run)


def tests_from_paths(paths: Sequence[str]) -> List[Test]:
    """Returns a list of tests from test executable paths."""

    tests: List[Test] = []
    for path in paths:
        name = os.path.splitext(os.path.basename(path))[0]
        tests.append(Test(name, path))
    return tests


async def find_and_run_tests(
    root: str,
    runner: str,
    timeout: Optional[float],
    runner_args: Sequence[str] = (),
    group: Optional[Sequence[str]] = None,
    test: Optional[Sequence[str]] = None,
) -> int:
    """Runs some unit tests."""

    if test:
        tests = tests_from_paths(test)
    else:
        tests = tests_from_groups(group, root)

    test_runner = TestRunner(runner, runner_args, tests, timeout)
    await test_runner.run_tests()

    return 0 if test_runner.all_passed() else 1


def main() -> int:
    """Run Pigweed unit tests built using GN."""

    parser = argparse.ArgumentParser(description=main.__doc__)
    register_arguments(parser)
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='Output additional logs as the script runs')

    args_as_dict = dict(vars(parser.parse_args()))
    del args_as_dict['verbose']
    return asyncio.run(find_and_run_tests(**args_as_dict))


if __name__ == '__main__':
    pw_cli.log.install(hide_timestamp=True)
    sys.exit(main())
