# Copyright 2023 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Implementation of test selection logic for `fx test`.

`fx test` supports fuzzy matching of tests across a number of
dimensions. This module implements selection and provides data
wrappers for the outcomes of the selection process.
"""

import asyncio
from collections import defaultdict
from dataclasses import dataclass
from enum import Enum
import itertools
import os
import re
import shutil
import tempfile
import typing

import environment
import event
import execution
import selection_types
from test_list_file import Test


class SelectionError(Exception):
    """There was an error preventing test selection from continuing."""


class SelectionMode(Enum):
    ANY = 0
    HOST = 1
    DEVICE = 2
    E2E = 3


# Default threshold for matching.
DEFAULT_FUZZY_DISTANCE_THRESHOLD: int = 3

# Large number to avoid matching a string.
NO_MATCH_DISTANCE: int = 1000000

# Perfect matches are distance 0.
PERFECT_MATCH_DISTANCE: int = 0


async def select_tests(
    entries: list[Test],
    selection: list[str],
    exec_env: environment.ExecutionEnvironment,
    mode: SelectionMode = SelectionMode.ANY,
    fuzzy_distance_threshold: int = DEFAULT_FUZZY_DISTANCE_THRESHOLD,
    recorder: event.EventRecorder | None = None,
    exact_match: bool = False,
    override_matcher_path: list[str] | None = None,
) -> selection_types.TestSelections:
    """Perform selection on the incoming list of tests.

    Selection may be passed directly from the command line. Each selection entry
    is implicitly ORed with adjacent entries unless a `--and` argument separates them.

    The --package and --component arguments each take a single argument.

    Args:
        entries (list[Test]): Tests to select from.
        selection (list[str]): Selection command line.
        exec_env (ExecutionEnvironment): The environment used to construct paths to tools.
        mode (SelectionMode, optional): Selection mode. Defaults to ANY.
        fuzzy_distance_threshold (int, optional): Distance threshold for including tests in selection.
        recorder (EventRecorder, optional): If set, record match duration events.
        exact_match (bool, optional): If set, force exact matches only. Otherwise do fuzzy matching.

    Raises:
        RuntimeError: If the required dldist script is not found
        SelectionError: If the selections were invalid

    Returns:
        TestSelections: Description of the selection process outcome.
    """

    filtered_entry_scores: dict[str, int] = {}
    if mode == SelectionMode.HOST:
        filtered_entry_scores = {
            test.name(): NO_MATCH_DISTANCE
            for test in entries
            if not test.is_host_test()
        }
        entries = list(filter(Test.is_host_test, entries))
    elif mode == SelectionMode.DEVICE:
        filtered_entry_scores = {
            test.name(): NO_MATCH_DISTANCE
            for test in entries
            if not test.is_pure_device_test()
        }
        entries = list(filter(Test.is_pure_device_test, entries))
    elif mode == SelectionMode.E2E:
        filtered_entry_scores = {
            test.name(): NO_MATCH_DISTANCE
            for test in entries
            if not test.is_e2e_test()
        }
        entries = list(filter(Test.is_e2e_test, entries))

    def make_final_scores(partial: dict[str, int]) -> dict[str, int]:
        filtered_entry_scores.update(partial)
        return filtered_entry_scores

    if not selection:
        if exact_match:
            raise SelectionError(
                "A selection is required when --exact is specified"
            )
        # If no selection text is specified, select all tests and
        # report them all as perfect matches.
        return selection_types.TestSelections(
            entries.copy(),
            [],
            make_final_scores({test.name(): 0 for test in entries}),
            [],
            fuzzy_distance_threshold,
        )

    match_groups = _parse_selection_command_line(selection)

    tests_to_run: set[Test] = set()
    group_matches: list[tuple[selection_types.MatchGroup, list[str]]] = []
    best_matches: dict[str, int] = defaultdict(lambda: NO_MATCH_DISTANCE)
    TRAILING_PATH = re.compile(r"/([\w\-_\.]+)$")
    COMPONENT_REGEX = re.compile(r"#meta/([\w\-_]+)\.cm")
    TRAILING_LABEL_TOOLCHAIN = re.compile(r"\(\$[^\)]+\)$")

    def extract_label(entry: Test) -> str:
        source_label = entry.build.test.label
        return TRAILING_LABEL_TOOLCHAIN.sub("", source_label)

    def extract_name(entry: Test) -> str:
        return entry.name()

    def extract_component(entry: Test) -> str | None:
        if entry.build.test.package_url is None:
            return None
        m = COMPONENT_REGEX.findall(entry.build.test.package_url)
        return m[0] if m else None

    def extract_trailing_path(entry: Test) -> str | None:
        if entry.build.test.path is None:
            return None
        m = TRAILING_PATH.findall(entry.build.test.path)
        return m[0] if m else None

    def extract_package(entry: Test) -> str | None:
        return entry.package_name()

    match_tasks = []

    for group in match_groups:

        async def task_handler(group: selection_types.MatchGroup) -> None:
            matched: list[str] = []
            id: event.Id | None = None
            if recorder is not None:
                # Hide the children of this event group. The runtime
                # and output of the programs run under the group are
                # useful in the log output, but too verbose to include
                # in the status output.
                id = recorder.emit_event_group(
                    f"Matching {group}", hide_children=True
                )

            matcher_prefix = exec_env.fx_cmd_line("dldist")

            label = _TestDistanceMeasurer(
                entries, extract_label, matcher_script_prefix=matcher_prefix
            )
            name = _TestDistanceMeasurer(
                entries, extract_name, matcher_script_prefix=matcher_prefix
            )
            component = _TestDistanceMeasurer(
                entries, extract_component, matcher_script_prefix=matcher_prefix
            )
            package = _TestDistanceMeasurer(
                entries, extract_package, matcher_script_prefix=matcher_prefix
            )
            trailing_path = _TestDistanceMeasurer(
                entries,
                extract_trailing_path,
                matcher_script_prefix=matcher_prefix,
            )

            async def closest_name_match() -> list[_TestDistance]:
                lowest_score_dict: defaultdict[Test, int] = defaultdict(
                    lambda: NO_MATCH_DISTANCE
                )
                tests = []
                if not exact_match:
                    tasks = (
                        [label.distances(n, recorder, id) for n in group.names]
                        + [name.distances(n, recorder, id) for n in group.names]
                        + [
                            component.distances(n, recorder, id)
                            for n in group.names
                        ]
                        + [
                            package.distances(n, recorder, id)
                            for n in group.names
                        ]
                        + [
                            trailing_path.distances(n, recorder, id)
                            for n in group.names
                        ]
                    )
                else:
                    # In exact mode, don't match names against
                    # anything but the name and label fields.
                    #
                    # For host tests, still allow exact matches against last
                    # segment of the name for more succinct selections.
                    tasks = (
                        [
                            label.distances(n, recorder, id, exact=True)
                            for n in group.names
                        ]
                        + [
                            name.distances(n, recorder, id, exact=True)
                            for n in group.names
                        ]
                        + [
                            trailing_path.distances(n, recorder, id, exact=True)
                            for n in group.names
                        ]
                    )
                results: list[list[_TestDistance]] = await asyncio.gather(
                    *tasks
                )
                for result in itertools.chain(*results):
                    if result.test not in lowest_score_dict:
                        tests.append(result.test)
                    lowest_score_dict[result.test] = min(
                        lowest_score_dict[result.test], result.distance
                    )

                return [
                    _TestDistance(test, lowest_score_dict[test])
                    for test in tests
                ]

            match_tries = (
                [closest_name_match()]
                + [
                    component.distances(c, recorder, id, exact=exact_match)
                    for c in group.components
                ]
                + [
                    package.distances(p, recorder, id, exact=exact_match)
                    for p in group.packages
                ]
            )

            distances: list[list[_TestDistance]] = await asyncio.gather(
                *match_tries
            )
            match_distances: dict[Test, int] = dict()
            for td in itertools.chain(*distances):
                # The final score for a match group is the worst match
                # out of the above sets of scores.
                if (old_val := match_distances.get(td.test)) is not None:
                    val = max(old_val, td.distance)
                else:
                    val = td.distance

                match_distances[td.test] = val

            for entry in entries:
                final_score = match_distances.get(entry)
                if final_score is None:
                    final_score = NO_MATCH_DISTANCE

                if exact_match and final_score != PERFECT_MATCH_DISTANCE:
                    # Allow only exact matches in exact match mode.
                    final_score = NO_MATCH_DISTANCE

                # Perform bookkeeping for debug output.
                best_matches[entry.name()] = min(
                    best_matches[entry.name()], final_score
                )

                # Record this test if it is now selected.
                if final_score <= fuzzy_distance_threshold:
                    matched.append(entry.name())
                    tests_to_run.add(entry)
            group_matches.append((group, matched))

            if recorder is not None and id is not None:
                recorder.emit_end(id=id)

        match_tasks.append(asyncio.create_task(task_handler(group)))

    done, pending = await asyncio.wait(
        match_tasks, return_when=asyncio.FIRST_EXCEPTION
    )

    # Stop any pending tasks after exception.
    if pending:
        t: asyncio.Task[None]
        for t in pending:
            t.cancel()

    # Find the exception and raise it.
    d: asyncio.Task[None]
    for d in done:
        d.result()

    omitted_fuzzy_matches: list[Test] = []
    if PERFECT_MATCH_DISTANCE in best_matches.values():
        # There was a perfect match. Omit any test that is not a perfect match.
        omitted_fuzzy_matches = [
            t
            for t in tests_to_run
            if best_matches[t.name()] != PERFECT_MATCH_DISTANCE
        ]
        tests_to_run = {
            t
            for t in tests_to_run
            if best_matches[t.name()] == PERFECT_MATCH_DISTANCE
        }

    # Ensure tests match the input ordering for consistency.
    selected_tests = [e for e in entries if e in tests_to_run]

    return selection_types.TestSelections(
        selected_tests,
        omitted_fuzzy_matches,
        make_final_scores(dict(best_matches)),
        group_matches,
        fuzzy_distance_threshold,
    )


@dataclass
class _TestDistance:
    test: Test
    distance: int


class _TestDistanceMeasurer:
    def __init__(
        self,
        tests: list[Test],
        extractor: typing.Callable[[Test], str | None],
        matcher_script_prefix: list[str],
    ) -> None:
        self._test_and_key = [
            (test, y) for test in tests if (y := extractor(test)) is not None
        ]
        self._matcher_script_prefix = matcher_script_prefix
        self._temp_dir: tempfile.TemporaryDirectory[str] | None = None
        self._input_file_path: str | None = None

    def _get_input_file(self) -> str:
        if self._input_file_path is None:
            self._temp_dir = tempfile.TemporaryDirectory()
            self._input_file_path = os.path.join(
                self._temp_dir.name, "temp-input.txt"
            )
            with open(self._input_file_path, "w") as f:
                f.write("\n".join([v[1] for v in self._test_and_key]))
                f.flush()
        return self._input_file_path

    def cleanup(self) -> None:
        if self._temp_dir is not None:
            self._temp_dir.cleanup()
            self._temp_dir = None
            self._input_file_path = None

    def __del__(self) -> None:
        self.cleanup()

    async def distances(
        self,
        value: str,
        recorder: event.EventRecorder | None,
        parent_id: event.Id | None,
        exact: bool = False,
    ) -> list[_TestDistance]:
        """Process and return the list of match distances for the list.

        Args:
            value (str): Value to compare against.
            recorder (event.EventRecorder | None): Recorder for events.
            parent_id (event.Id | None): ID of the event to nest under.
            exact (bool, optional): If true, force exact matches only. Defaults to False.

        Raises:
            RuntimeError: The required matching script is missing.

        Returns:
            list[_TestDistance]: Description of distances from contained set
            of tests to the input value.
        """
        file_name = self._get_input_file()

        program_prefix = self._matcher_script_prefix

        if program_prefix and program_prefix[0] == "fx":
            if not shutil.which("fx"):
                # There is no fx available, which means we may be in a test scenario.
                # Try to construct a path to the dldist data dependency.
                cur_dir = os.path.dirname(os.path.dirname(__file__))
                dldist_path = os.path.join(cur_dir, "bin", "dldist")
                if os.path.exists(dldist_path):
                    # Only override if we are actually in a test scenario.
                    program_prefix = [dldist_path]

        arg_suffix = [
            "--needle",
            value,
            "--input",
            file_name,
        ] + (["--match-contains"] if not exact else [])
        output = await execution.run_command(
            *program_prefix,
            *arg_suffix,
            recorder=recorder,
            parent=parent_id,
            do_not_log_output=True,
        )

        if output is None:
            raise RuntimeError(
                f"Failed to execute matcher script at {program_prefix}."
            )
        elif output.return_code != 0:
            raise RuntimeError(f"Matching program failed:\n{output.stderr}")

        vals = [int(line) for line in output.stdout.strip().splitlines()]
        return [
            _TestDistance(t[0], v) for t, v in zip(self._test_and_key, vals)
        ]


def _parse_selection_command_line(
    selection: list[str],
) -> list[selection_types.MatchGroup]:
    selection = selection.copy()  # Do not affect input list.
    output_groups: list[selection_types.MatchGroup] = []
    cur_group: selection_types.MatchGroup | None = None

    def pop_for_arg(arg: str) -> None:
        """Mutate the outer cur_group variable depending on the contents of the argument.

        This closure handles parameters that take a value.

        Args:
            arg (str): Name of the argument expecting a value.

        Raises:
            RuntimeError: If an unknown argument was passed
            SelectionError: If a value is expected but we reached the end of the input.
        """
        nonlocal cur_group
        assert cur_group
        assert arg in ["--package", "--component"]
        try:
            token = selection.pop(0)
            if arg == "--package":
                cur_group.packages.add(token)
            elif arg == "--component":
                cur_group.components.add(token)
        except IndexError:
            raise SelectionError(f"Missing value for flag {arg}")

    def rotate_group() -> None:
        """Start populating a new MatchGroup. If the current group
        is not empty, keep track of it first.
        """
        nonlocal cur_group
        if cur_group:
            output_groups.append(cur_group)
        cur_group = selection_types.MatchGroup()

    special_tokens = ["--package", "--component"]
    while selection:
        # Keep popping tokens, accounting for those that require another argument.
        token = selection.pop(0)
        if token == "--and":
            if not cur_group:
                raise SelectionError(
                    "Cannot use --and at the beginning of a selection"
                )
            try:
                token = selection.pop(0)
                if token == "--and":
                    raise SelectionError(
                        "Cannot use --and immediately after --and"
                    )
                if token in special_tokens:
                    pop_for_arg(token)
                else:
                    cur_group.names.add(token)

            except IndexError:
                raise SelectionError(
                    "--and must be followed by another selection"
                )
        elif token in special_tokens:
            rotate_group()
            pop_for_arg(token)
        else:
            rotate_group()
            assert cur_group is not None
            cur_group.names.add(token)

    # Final rotation to get the last MatchGroup added to the output.
    rotate_group()

    return output_groups
