# 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.

import asyncio
from collections import defaultdict
from dataclasses import dataclass
import datetime
from itertools import chain
import os
import re
import time
import typing

import statusinfo
import termout

import args
import environment
import event


@dataclass
class DurationInfo:
    """Tracks an individual event duration.

    Events with started=True denote the beginning of a duration and must be
    matched by an event with ending=True and the same Id.

    Instances of this class track durations over time for display purposes.
    """

    # A formatted name for the duration, used as a label.
    name: str

    # The start monotonic time.
    start_monotonic: float

    # The optional parent of the duration.
    parent: event.Id | None

    # The number of expected children. If set, we can show a progress bar.
    expected_child_tasks: int = 0

    # If True, hide children of this duration from the display.
    hide_children: bool = False

    # If True, do not display this duration in the list.
    hide_from_display: bool = False


@dataclass
class DurationPrintInfo:
    """Wrap information needed to print the status of a task duration."""

    # The DurationInfo we will print.
    info: DurationInfo

    # How far indented the duration should be.
    indent: int

    # If set, display a progress bar with this percent completion.
    progress: float | None = None


@dataclass
class TaskStatus:
    """Overall status of all tasks, for printing."""

    # Number of tasks currently running.
    tasks_running: int

    # Number of tasks that have completed
    tasks_complete: int

    # Number of tasks that are queued but have not started running yet.
    tasks_queued_but_not_running: int

    # Detailed information to print a status line for each in-progress duration.
    duration_infos: list[DurationPrintInfo]

    def total_tasks(self) -> int:
        return (
            self.tasks_running
            + self.tasks_complete
            + self.tasks_queued_but_not_running
        )


class ConsoleState:
    """Holder for all console output state.

    Attributes:
        active_durations: Map from Id to DurationInfo for durations
            that have not yet ended.
        complete_durations: Map from Id to DurationInfo for durations
            that have ended.
        end_duration: The elapsed time for the entire run, measured
            as the difference between the start and end of GLOBAL_RUN_ID.
            Only set after the global run has ended.
        test_results: Map from status to a set of tests with that
            status. This is the canonical result list for all tests.
        exec_env: Parsed environment for this run.
    """

    def __init__(self) -> None:
        self.active_durations: dict[event.Id, DurationInfo] = dict()
        self.complete_durations: dict[event.Id, DurationInfo] = dict()
        self.end_duration: float | None = None
        self.test_results: dict[
            event.TestSuiteStatus, typing.Set[str]
        ] = defaultdict(set)
        self.exec_env: environment.ExecutionEnvironment | None = None
        self.ended_due_to_error = False


class ConsoleOutput:
    def __init__(
        self,
        monotonic_time_source: typing.Callable[
            [], float
        ] = lambda: time.monotonic(),
    ):
        """A wrapper for console output routines.

        Args:
            monotonic_time_source (Callable[[], float]): Source of monotonic time,
                injectable for test and replay scenarios.
        """
        self._monotonic_time_source = monotonic_time_source

    async def console_printer(
        self,
        recorder: event.EventRecorder,
        flags: args.Flags,
        do_status_output_event: asyncio.Event,
    ) -> None:
        """Asynchronous future that implements console printing.

        Continually reads events from the given recorder and presents status
        updates to the terminal. This is the main output routine for fx test.

        Output is controlled by the given flags.

        This routine implements continual clearing and updating of a status
        bar at the bottom of the user's terminal. This behavior is controlled
        by the `do_status_output_event` asyncio.Event, which is set only when
        continual status output is both desired and available.

        Args:
            recorder (event.EventRecorder): Source of events to display.
            flags (args.Flags): Command line flags to control formatting.
            do_status_output_event (asyncio.Event): Display updating
                status bar only if this is set.
        """

        state = ConsoleState()
        print_queue: asyncio.Queue[list[str]] = asyncio.Queue()

        # Spawn an asynchronous task to actually process incoming events.
        # The rest of this method simply displays the status output and prints
        # lines that are requested by the other task.
        event_loop = asyncio.create_task(
            _console_event_loop(recorder, flags, state, print_queue)
        )

        # Keep pumping events until there will be no more.
        while not event_loop.done() or not print_queue.empty():
            # First try to get some lines that need to be printed.
            # If there is nothing to print by the time we need to refresh, timeout
            # and refresh the output.
            try:
                lines_to_print = await asyncio.wait_for(
                    print_queue.get(), flags.status_delay
                )
            except asyncio.TimeoutError:
                lines_to_print = []

            if do_status_output_event.is_set():
                status_lines = self._create_status_lines_from_state(
                    flags, state
                )

                # Print status output, leaving an extra line to separate
                # from prepended lines.
                termout.write_lines(
                    [""] + status_lines[: flags.status_lines], lines_to_print
                )
            elif lines_to_print:
                print("\n".join(lines_to_print))

        # We are done with all events, clean up and exit.

        if do_status_output_event.is_set():
            # Clear status output.
            termout.write_lines([], [])

        if state.test_results:
            passed = len(state.test_results[event.TestSuiteStatus.PASSED])
            failed = (
                len(state.test_results[event.TestSuiteStatus.FAILED])
                + len(state.test_results[event.TestSuiteStatus.TIMEOUT])
                + len(state.test_results[event.TestSuiteStatus.FAILED_TO_START])
            )
            skipped = len(state.test_results[event.TestSuiteStatus.SKIPPED])
            passed_text = pass_format(passed, flags.style)
            failed_text = fail_format(failed, flags.style)
            skipped_text = skip_format(skipped, flags.style)

            print(
                f"\nRAN: {passed+failed} | {passed_text} | {failed_text} | {skipped_text}"
            )

            def print_tests(prefix: str, names: list[str]) -> None:
                for name in names:
                    print(statusinfo.error_highlight(f"{prefix}: {name}"))

            print_tests(
                "FAILED TO START",
                sorted(
                    state.test_results[event.TestSuiteStatus.FAILED_TO_START]
                ),
            )
            print_tests(
                "TIMEOUT",
                sorted(state.test_results[event.TestSuiteStatus.TIMEOUT]),
            )
            print_tests(
                "FAILED",
                sorted(state.test_results[event.TestSuiteStatus.FAILED]),
            )

        if state.end_duration is not None:
            print(
                statusinfo.dim(
                    f"\nCompleted in {state.end_duration:.3f}s",
                    style=flags.style,
                )
            )
        else:
            prefix = (
                statusinfo.highlight("[REPLAY] ", style=flags.style)
                if flags.is_replay()
                else ""
            )
            print(
                "\n"
                + prefix
                + statusinfo.error_highlight(
                    "Execution cancelled.",
                    style=flags.style,
                )
            )

        if (
            state.active_durations
            and not state.ended_due_to_error
            and not flags.is_replay()
        ):
            print(
                statusinfo.error_highlight(
                    "BUG: Durations still active at exit:", style=flags.style
                )
            )
            for id, duration in state.active_durations.items():
                print(f" {id} = {duration.__dict__}")

        await event_loop

    def _create_status_lines_from_state(
        self, flags: args.Flags, state: ConsoleState
    ) -> list[str]:
        """Process the overall console state into a list of lines to present to the user.

        Args:
            flags (args.Flags): Flags controlling output format.
            state (ConsoleState): The console state to process.

        Returns:
            list[str]: List of lines to present to the user.
        """

        # Process the state
        task_status = self._produce_task_status_from_state(state)

        # Current time for duration displays.
        monotonic = self._monotonic_time_source()

        # Format the computed data as lines to print out.
        status_lines = self._format_duration_lines(flags, task_status)

        # Show an overall duration timer if the global run is started.
        if event.GLOBAL_RUN_ID in state.active_durations:
            run_duration = f"[duration: {statusinfo.format_duration(datetime.timedelta(seconds=monotonic - state.active_durations[event.GLOBAL_RUN_ID].start_monotonic).total_seconds())}]"
        else:
            run_duration = ""

        # Show pass/fail counts if tests have started completing.
        pass_fail = ""
        if state.test_results:
            passed = len(state.test_results[event.TestSuiteStatus.PASSED])
            failed = (
                len(state.test_results[event.TestSuiteStatus.FAILED])
                + len(state.test_results[event.TestSuiteStatus.TIMEOUT])
                + len(state.test_results[event.TestSuiteStatus.FAILED_TO_START])
            )
            skipped = len(state.test_results[event.TestSuiteStatus.SKIPPED])
            passed_text = pass_format(passed, flags.style)
            failed_text = fail_format(failed, flags.style)
            skipped_text = skip_format(skipped, flags.style)

            pass_fail = (
                statusinfo.dim(" [tests: ", style=flags.style)
                + f"{passed_text} {failed_text} {skipped_text}"
                + statusinfo.dim("] ", style=flags.style)
            )

        # Print out the duration lines if they are present.
        if status_lines:
            status_lines = [
                (
                    (
                        ""
                        if not flags.is_replay()
                        else statusinfo.highlight(
                            "[REPLAY] ", style=flags.style
                        )
                    )
                    + statusinfo.green("Status: ", style=flags.style)
                    + statusinfo.dim(f"{run_duration}", style=flags.style)
                    + ("" if not pass_fail else pass_fail)
                )
            ] + status_lines

        return status_lines

    def _produce_task_status_from_state(
        self, state: ConsoleState
    ) -> TaskStatus:
        # Generate a mapping of each duration to its children.
        duration_children: dict[event.Id, list[event.Id]] = defaultdict(list)
        all_durations: dict[event.Id, DurationInfo] = dict()

        for id, duration in chain(
            state.active_durations.items(), state.complete_durations.items()
        ):
            if id != event.GLOBAL_RUN_ID and not duration.hide_from_display:
                duration_children[
                    duration.parent or event.GLOBAL_RUN_ID
                ].append(id)
            all_durations[id] = duration

        # Calculate counts of how many tasks are in what state.
        tasks_running = len(state.active_durations)
        tasks_complete = len(state.complete_durations)
        tasks_queued_but_not_running = 0
        for id, children in duration_children.items():
            expected = all_durations[id].expected_child_tasks
            if expected and expected >= len(children):
                tasks_queued_but_not_running += expected - len(children)

        # Process the active durations into DurationPrintInfo, which
        # contains information on how to print the duration state.
        # We perform an in-order tree traversal over all durations
        # starting from the root, taking account only of those
        # durations that are active and sorting by descending
        # timestamp.
        duration_print_infos: list[DurationPrintInfo] = []
        assert event.GLOBAL_RUN_ID in all_durations

        # Stack of duration event.Ids to process. Second
        # element of the tuple tracks indent level.
        work_stack: list[tuple[event.Id, int]] = [(event.GLOBAL_RUN_ID, 0)]
        while work_stack:
            id, indent = work_stack.pop()
            info: DurationInfo | None = None

            if id == event.GLOBAL_RUN_ID:
                pass
            elif id not in state.active_durations:
                continue
            else:
                progress = None
                info = state.active_durations[id]
                if info.expected_child_tasks:
                    progress = min(
                        1.0,
                        sum(
                            [
                                1 if child_id in state.complete_durations else 0
                                for child_id in duration_children.get(id, [])
                            ]
                        )
                        / info.expected_child_tasks,
                    )
                duration_print_infos.append(
                    DurationPrintInfo(info, indent, progress)
                )

            if info is not None and info.hide_children:
                # Skip processing children of this duration for display.
                continue

            for child_id in duration_children.get(id, []):
                children = []
                if child_id in state.active_durations:
                    children.append(child_id)
                # Put children in the work stack in ascending
                # order, so that they will be popped in descending
                # order.
                children.sort(key=lambda x: all_durations[x].start_monotonic)
                work_stack.extend(
                    [(child_id, indent + 1) for child_id in children]
                )

        return TaskStatus(
            tasks_running=tasks_running,
            tasks_complete=tasks_complete,
            tasks_queued_but_not_running=tasks_queued_but_not_running,
            duration_infos=duration_print_infos,
        )

    def _format_duration_lines(
        self, flags: args.Flags, status: TaskStatus
    ) -> list[str]:
        """Given the processed status for all tasks, format output based
        on the flags.

        Args:
            flags (args.Flags): Flags to control output format.
            status (TaskStatus): Processed task status.

        Returns:
            list[str]: A list of lines to present to the user.
        """
        monotonic = self._monotonic_time_source()
        duration_lines: list[str] = []
        for print_info in status.duration_infos:
            prefix = " " * (print_info.indent * 2)
            if print_info.progress is not None:
                duration_lines.append(
                    statusinfo.status_progress(
                        prefix + print_info.info.name,
                        print_info.progress,
                        style=flags.style,
                    )
                )
            else:
                duration_lines.append(
                    statusinfo.duration_progress(
                        prefix + print_info.info.name,
                        datetime.timedelta(
                            seconds=monotonic - print_info.info.start_monotonic
                        ),
                        style=flags.style,
                    )
                )
        return duration_lines


class TestExecutionInfo:
    """Track and record a single test suite's execution."""

    def __init__(self, name: str):
        """Initialize execution info for a named suite.

        Args:
            name (str): The test suite's name.
        """
        self.name: str = name
        self.buffered_lines: list[str] = []
        self.buffered_output_task: asyncio.Task[None] | None = None

    def spawn_buffered_output_printer(
        self, timeout: float, queue: asyncio.Queue[list[str]]
    ) -> None:
        """Spawn an async task that will print buffered lines after a timeout.

        Args:
            timeout (float): Seconds to wait before printing buffered data.
            queue (asyncio.Queue[list[str]]): Queue to print the
                buffered data to upon timeout.
        """

        async def output_printer_task() -> None:
            """Task that handles sleeping and then sending queued lines.

            May be asynchronously canceled.
            """
            await asyncio.sleep(timeout)
            await queue.put(self.buffered_lines)
            self.buffered_lines = []  # drop to release memory

        self.buffered_output_task = asyncio.create_task(output_printer_task())

    def print_verbatim(self) -> bool:
        """Determine if an output printer should skip buffering and just print.

        Returns:
            bool: True if output should be printed verbatim, False otherwise.
        """
        return (task := self.buffered_output_task) is not None and task.done()

    def should_buffer_output(self) -> bool:
        """Determine if output should be buffered.

        Returns:
            bool: True if an output printer should buffer lines in
                this object, False otherwise.
        """
        return (
            task := self.buffered_output_task
        ) is not None and not task.done()

    def cleanup(self) -> None:
        """Clean up any buffers, cancel, print tasks, and drop any buffered output."""
        if (
            self.buffered_output_task is not None
            and not self.buffered_output_task.done()
        ):
            self.buffered_output_task.cancel()
            self.buffered_lines = []


async def _console_event_loop(
    recorder: event.EventRecorder,
    flags: args.Flags,
    state: ConsoleState,
    print_queue: asyncio.Queue[list[str]],
) -> None:
    """Internal event processor.

    This task processes the events generated by the given EventRecorder and
    updates the given ConsoleState based on their contents. It may also
    request that some lines be printed for the user to see.

    Args:
        recorder (event.EventRecorder): Source of events to process.
        flags (args.Flags): Command line flags for this invocation.
        state (ConsoleState): Shared state object to update over time.
        print_queue (asyncio.Queue): Queue for lines to print to the user.
    """

    # Keep track of ids corresponding to test suites for display purposes:
    # 1. We need the name to report success or failure.
    # 2. We flatten the status display so that commands run as
    #    part of a test execution are not shown.
    # 3. We can buffer output from those programs for later display using
    #    the --slow flag.
    test_suite_execution_info: dict[event.Id, TestExecutionInfo] = dict()

    # Keep track of task IDs that are nested under a test suite.
    # This is needed to map buffered program output to the correct test suite.
    event_id_to_test_suite: dict[event.Id, event.Id] = dict()

    # Keep track of active build IDs and programs that are part of a build.
    active_build_ids: set[event.Id] = set()
    event_id_to_build: dict[event.Id, event.Id] = dict()
    next_event: event.Event
    async for next_event in recorder.iter():
        lines_to_print: list[str] = []

        # If set, and we do verbose printing, append this suffix to the output.
        verbose_suffix: str = ""

        old_duration: DurationInfo | None = None
        if next_event.ending and next_event.id is not None:
            active_build_ids.discard(next_event.id)
            if next_event.id in event_id_to_build:
                del event_id_to_build[next_event.id]

        if (
            next_event.ending
            and next_event.id is not None
            and next_event.id in state.active_durations
        ):
            old_duration = state.active_durations.pop(next_event.id)
            state.complete_durations[next_event.id] = old_duration
            elapsed_time = next_event.timestamp - old_duration.start_monotonic
            verbose_suffix = (
                f" [duration={datetime.timedelta(seconds=elapsed_time)}]"
            )
            if next_event.id == event.GLOBAL_RUN_ID:
                state.end_duration = elapsed_time
                state.ended_due_to_error = next_event.error is not None

        if flags.verbose:
            # In verbose mode, refuse to print too many output characters
            # to avoid scrolling info out of view.
            lines_to_print.append(
                statusinfo.ellipsize(recorder.event_string(next_event), 400)
                + verbose_suffix
            )

        if next_event.payload:
            if (
                next_event.id is not None
                and next_event.starting
                and next_event.parent not in test_suite_execution_info
            ):
                # Provide nice formatting for event types that need to be tracked for a duration.

                if next_event.id == event.GLOBAL_RUN_ID:
                    state.active_durations[next_event.id] = DurationInfo(
                        "fx test",
                        next_event.timestamp,
                        parent=next_event.parent,
                    )
                elif next_event.payload.parsing_file is not None:
                    styled_name = statusinfo.highlight(
                        "parsing", style=flags.style
                    )
                    state.active_durations[next_event.id] = DurationInfo(
                        f"{styled_name} {next_event.payload.parsing_file.name}",
                        next_event.timestamp,
                        parent=next_event.parent,
                    )
                elif next_event.payload.program_execution is not None:
                    is_build = (
                        next_event.parent is not None
                        and next_event.parent in active_build_ids
                    ) or (
                        bool(next_event.payload.program_execution.flags)
                        and "build"
                        in next_event.payload.program_execution.flags
                    )
                    if is_build:
                        if next_event.id is not None:
                            event_id_to_build[next_event.id] = (
                                next_event.parent or next_event.id
                            )
                        styled_name = statusinfo.highlight(
                            "Building...", style=flags.style
                        )
                        state.active_durations[next_event.id] = DurationInfo(
                            styled_name,
                            next_event.timestamp,
                            parent=next_event.parent,
                            hide_from_display=False,
                        )
                    else:
                        styled_name = statusinfo.highlight(
                            "running", style=flags.style
                        )
                        state.active_durations[next_event.id] = DurationInfo(
                            f"{styled_name} {next_event.payload.program_execution.to_formatted_command_line()}",
                            next_event.timestamp,
                            parent=next_event.parent,
                            hide_from_display=next_event.payload.program_execution.quiet_mode,
                        )
                elif (
                    next_event.payload.event_group is not None
                    or next_event.payload.test_group is not None
                ):
                    group: event.EventGroupPayload = next_event.payload.event_group or next_event.payload.test_group  # type: ignore
                    styled_name = statusinfo.highlight(
                        group.name, style=flags.style
                    )
                    state.active_durations[next_event.id] = DurationInfo(
                        styled_name,
                        next_event.timestamp,
                        parent=next_event.parent,
                        expected_child_tasks=group.queued_events or 0,
                        hide_children=group.hide_children,
                    )
                elif next_event.payload.build_targets:
                    if next_event.starting and next_event.id is not None:
                        active_build_ids.add(next_event.id)
                    styled_name = statusinfo.highlight(
                        f"Refreshing {len(next_event.payload.build_targets)} targets",
                        style=flags.style,
                    )
                    state.active_durations[next_event.id] = DurationInfo(
                        styled_name,
                        next_event.timestamp,
                        parent=next_event.parent,
                    )
                elif next_event.payload.test_suite_started:
                    styled_name = statusinfo.highlight(
                        next_event.payload.test_suite_started.name,
                        style=flags.style,
                    )
                    state.active_durations[next_event.id] = DurationInfo(
                        styled_name,
                        next_event.timestamp,
                        parent=next_event.parent,
                    )
                else:
                    # Fallback. Display an ugly error if this is triggered so that we can fix the bug.
                    styled_name = statusinfo.error_highlight(
                        f"BUG: no title for {next_event.payload.to_dict()}",  # type:ignore
                        style=flags.style,
                    )
                    state.active_durations[next_event.id] = DurationInfo(
                        styled_name,
                        next_event.timestamp,
                        parent=next_event.parent,
                    )

            if (
                next_event.id is not None
                and next_event.parent is not None
                and next_event.parent in test_suite_execution_info
            ):
                # Track direct children of a test suite, so their
                # output can be buffered to the right suite.
                if next_event.starting:
                    event_id_to_test_suite[next_event.id] = next_event.parent
                elif next_event.ending:
                    del event_id_to_test_suite[next_event.id]

            if next_event.payload.process_env is not None:
                # Extract the path from the parsed environment.
                state.exec_env = next_event.payload.process_env
            elif next_event.payload.user_message is not None:
                # Style and display user messages.
                quietable = False
                msg = next_event.payload.user_message
                if msg.level == event.MessageLevel.INSTRUCTION:
                    quietable = True
                    text = statusinfo.dim(msg.value, style=flags.style)
                elif msg.level == event.MessageLevel.WARNING:
                    text = statusinfo.warning(msg.value, style=flags.style)
                elif msg.level == event.MessageLevel.INFO:
                    quietable = True
                    text = msg.value
                elif msg.level == event.MessageLevel.VERBATIM:
                    text = msg.value
                else:
                    text = msg.value
                if not quietable or not flags.quiet:
                    lines_to_print.append(text)
            elif next_event.payload.program_output is not None:
                output = next_event.payload.program_output

                if output.data.endswith("\n"):
                    data = output.data[:-1]
                else:
                    data = output.data

                if (
                    next_event.id is not None
                    and next_event.id in event_id_to_build
                ):
                    if next_event.id in state.active_durations:
                        lines = [
                            line.strip()
                            for line in re.split(r"[\r\n]+", output.data)
                            if line.strip()
                        ]
                        if lines:
                            state.active_durations[next_event.id].name = lines[
                                -1
                            ]
                            if print_queue.empty():
                                await print_queue.put([])
                elif output.print_verbatim:
                    # If a program execution requests verbatim output,
                    # print to console.
                    lines_to_print.append(data)
                elif (
                    next_event.id is not None
                    and (suite_id := event_id_to_test_suite.get(next_event.id))
                    is not None
                ):
                    # This output corresponds to a running suite.
                    suite_info = test_suite_execution_info[suite_id]
                    if suite_info.print_verbatim():
                        # Already timed out, just print this output verbatim.
                        lines_to_print.append(data)
                    elif suite_info.should_buffer_output():
                        # Awaiting timeout, buffer this output.
                        suite_info.buffered_lines.append(data)
            elif (
                next_event.payload.test_file_loaded is not None
                and not flags.quiet
            ):
                # Print a result to the user when the tests file is parsed.
                test_info = next_event.payload.test_file_loaded
                path = (
                    "//"
                    + os.path.relpath(
                        test_info.file_path, state.exec_env.fuchsia_dir
                    )
                    if state.exec_env
                    else test_info.file_path
                )
                lines_to_print.append(
                    f"\nFound {len(test_info.test_entries)} total tests in {statusinfo.green(path, style=flags.style)}"
                )
            elif next_event.payload.test_selections and not flags.quiet:
                # Print a result to the user when tests are selected.
                if not flags.quiet:
                    count = len(next_event.payload.test_selections.selected)
                    label = statusinfo.highlight(
                        f"{count} test{'s' if count != 1 else ''}",
                        style=flags.style,
                    )
                    suffix = statusinfo.highlight(
                        f" {flags.count} times" if flags.count > 1 else "",
                        style=flags.style,
                    )
                    lines_to_print.append(f"\nPlan to run {label}{suffix}")
            elif (
                next_event.payload.build_targets is not None and not flags.quiet
            ):
                # Print the number of targets we are refreshing.
                label = statusinfo.highlight(
                    f"{len(next_event.payload.build_targets)} targets",
                    style=flags.style,
                )
                lines_to_print.append(
                    f"\n{statusinfo.green('Refreshing', style=flags.style)} {label}"
                )
                # Also output the command line used for fx build up to a limit,
                # to avoid scrolling multiple pages.
                out_dir_string = (
                    f"--dir {state.exec_env.out_dir} " if state.exec_env else ""
                )
                lines_to_print.append(
                    statusinfo.ellipsize(
                        statusinfo.green_highlight(
                            f"> fx {out_dir_string}build {' '.join(next_event.payload.build_targets)}",
                            style=flags.style,
                        ),
                        width=80 * 5,  # Approximately 5 lines
                    ),
                )
            elif next_event.payload.test_group is not None:
                # Let the user know we intend to run a number of tests.
                val = statusinfo.highlight(
                    f"{next_event.payload.test_group.queued_events} tests",
                    style=flags.style,
                )
                label = statusinfo.green("Running", style=flags.style)
                lines_to_print.append(f"{label} {val}")
            elif next_event.payload.test_suite_started is not None:
                # Let the user know a test suite is starting.
                assert next_event.id
                suite_info = TestExecutionInfo(
                    next_event.payload.test_suite_started.name
                )
                test_suite_execution_info[next_event.id] = suite_info
                if flags.slow > 0:
                    suite_info.buffered_lines.extend(
                        [
                            statusinfo.dim(
                                f"Runtime has exceeded {flags.slow} seconds",
                                style=flags.style,
                            ),
                            f"Showing output for {test_suite_execution_info[next_event.id].name}",
                        ]
                    )
                    suite_info.spawn_buffered_output_printer(
                        flags.slow, print_queue
                    )

                label = "Starting:"
                val = statusinfo.green_highlight(
                    next_event.payload.test_suite_started.name,
                    style=flags.style,
                )
                # Explicitly mark if the suite is a host test or not hermetic.
                if next_event.payload.test_suite_started.is_host:
                    suffix_label = statusinfo.highlight(
                        "(HOST)", style=flags.style
                    )
                elif next_event.payload.test_suite_started.hermetic:
                    suffix_label = ""
                else:
                    suffix_label = statusinfo.warning(
                        "(NOT HERMETIC)", style=flags.style
                    )
                if not flags.quiet:
                    lines_to_print.append(f"\n{label} {val} {suffix_label}")
            elif next_event.payload.test_suite_ended is not None:
                # Let the user know a test suite has ended, and
                # what its status is.
                assert next_event.id
                payload = next_event.payload.test_suite_ended
                if payload.status == event.TestSuiteStatus.PASSED:
                    label = statusinfo.green_highlight(
                        "PASSED", style=flags.style
                    )
                elif payload.status == event.TestSuiteStatus.FAILED:
                    label = statusinfo.error_highlight(
                        "FAILED", style=flags.style
                    )
                elif payload.status == event.TestSuiteStatus.SKIPPED:
                    label = statusinfo.highlight("SKIPPED", style=flags.style)
                elif payload.status == event.TestSuiteStatus.ABORTED:
                    label = statusinfo.highlight("ABORTED", style=flags.style)
                elif payload.status == event.TestSuiteStatus.FAILED_TO_START:
                    label = statusinfo.error_highlight(
                        "FAILED TO START", style=flags.style
                    )
                elif payload.status == event.TestSuiteStatus.TIMEOUT:
                    label = statusinfo.error_highlight(
                        "TIMEOUT", style=flags.style
                    )
                else:
                    label = statusinfo.error_highlight(
                        "BUG: UNKNOWN", style=flags.style
                    )

                # Record status of the test, and stop tracking the test task.
                finished_test = test_suite_execution_info[next_event.id]
                state.test_results[payload.status].add(finished_test.name)
                finished_test.cleanup()
                del test_suite_execution_info[next_event.id]

                suffix = ""
                if payload.message and not flags.quiet:
                    suffix = "\n" + statusinfo.dim(payload.message) + "\n"

                lines_to_print.append(f"{label}: {finished_test.name}{suffix}")

            elif next_event.payload.enumerate_test_cases is not None:
                cases_payload = next_event.payload.enumerate_test_cases
                styled_name = statusinfo.green_highlight(
                    cases_payload.test_name, style=flags.style
                )
                lines_to_print.append(f"\nTest cases in {styled_name}:")
                for line in cases_payload.test_case_names:
                    lines_to_print.append(
                        f" {statusinfo.highlight(line, style=flags.style)}"
                    )
                    command = cases_payload.maybe_format_command(
                        test_name=cases_payload.test_name, test_case=line
                    )
                    if command is None:
                        command = f'fx test {cases_payload.test_name} --test-filter "{line}"'
                    lines_to_print.append(
                        f" {statusinfo.dim(command, style=flags.style)}"
                    )
            elif next_event.payload.load_config is not None and not flags.quiet:
                load_config = next_event.payload.load_config
                lines_to_print.extend(
                    [
                        statusinfo.highlight(
                            f"Default flags loaded from {load_config.path}:",
                            style=flags.style,
                        ),
                        statusinfo.dim(
                            f"{str(load_config.command_line)}\n",
                            style=flags.style,
                        ),
                    ]
                )

        if next_event.error:
            # Highlight all errors
            lines_to_print.extend(
                [
                    statusinfo.error_highlight(line, style=flags.style)
                    for line in ("ERROR: " + next_event.error).splitlines()
                ]
            )

        if lines_to_print:
            await print_queue.put(lines_to_print)


def pass_format(count: int, style: bool = True) -> str:
    """Helper to format passing tests.

    Args:
        count (int): The number of passing tests. Don't highlight for 0.
        style (bool, optional): Only style if True. Defaults to True.

    Returns:
        str: Formatted test count.
    """
    label = f"PASSED: {count}"
    if count > 0:
        return statusinfo.green_highlight(label, style=style)
    else:
        return statusinfo.dim(label, style=style)


def fail_format(count: int, style: bool = True) -> str:
    """Helper to format failing tests.

    Args:
        count (int): The number of failing tests. Don't highlight for 0.
        style (bool, optional): Only style if True. Defaults to True.

    Returns:
        str: Formatted test count.
    """
    label = f"FAILED: {count}"
    if count > 0:
        return statusinfo.error_highlight(label, style=style)
    else:
        return statusinfo.dim(label, style=style)


def skip_format(count: int, style: bool = True) -> str:
    """Helper to format skipped tests.

    Args:
        count (int): The number of skipped tests. Don't highlight for 0.
        style (bool, optional): Only style if True. Defaults to True.

    Returns:
        str: Formatted test count.
    """
    label = f"SKIPPED: {count}"
    if count > 0:
        return label
    else:
        return statusinfo.dim(label, style=style)
