#!/usr/bin/env fuchsia-vendored-python
# 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.
"""Common wrapper for running prebuilt tools remotely.

This script functions as a standalone executable.

Usage:
  $0 [remote options...] -- command...
"""

import argparse
import os
import subprocess
import sys

import cl_utils
import fuchsia
import remote_action

from pathlib import Path
from typing import Any, Iterable, Optional, Sequence

_SCRIPT_BASENAME = Path(__file__).name
_SCRIPT_DIR = Path(__file__).parent


def msg(text: str):
    print(f"[{_SCRIPT_BASENAME}] {text}")


def _main_arg_parser() -> argparse.ArgumentParser:
    """Construct the argument parser, called by main()."""
    parser = argparse.ArgumentParser(
        description="Prepares a command for remote execution.",
        argument_default=[],
        add_help=True,  # Want this to exit after printing --help
    )
    remote_action.inherit_main_arg_parser_flags(parser)
    parser.add_argument(
        "--label_toolname",  # "toolname" is a special label for rewrapper
        type=Path,
        default=None,
        metavar="toolpath",
        help="Identifies the action type for metrics purposes.  The basename of this tool is forwarded to `rewrapper --label=toolname=NAME`.",
    )
    return parser


_MAIN_ARG_PARSER = _main_arg_parser()


class PrebuiltToolAction(object):
    """Generic remote wrapper for running a tool in Fuchsia's prebuilts."""

    def __init__(
        self,
        argv: Sequence[str],
        exec_root: Path = None,
        working_dir: Path = None,
        host_platform: str = None,
        auto_reproxy: bool = True,  # can disable for unit-testing
    ):
        self._working_dir = (working_dir or Path(os.curdir)).absolute()
        self._exec_root = (exec_root or remote_action.PROJECT_ROOT).absolute()
        self._host_platform = host_platform or fuchsia.HOST_PREBUILT_PLATFORM

        # Propagate --remote-flag=... options to the remote prefix,
        # as if they appeared before '--'.
        # Forwarded rewrapper options with values must be written as '--flag=value',
        # not '--flag value' because argparse doesn't know what unhandled flags
        # expect values.
        main_argv, self._local_command = remote_action.forward_remote_flags(
            argv
        )

        # forward all unknown flags to rewrapper
        # --help here will result in early exit()
        (
            self._main_args,
            self._main_remote_options,
        ) = _MAIN_ARG_PARSER.parse_known_args(main_argv)

        # Re-launch with reproxy if needed.
        if auto_reproxy:
            remote_action.auto_relaunch_with_reproxy(
                script=Path(__file__), argv=argv, args=self._main_args
            )

        if not self.local_command:  # there is no command, bail out early
            return

        self._local_only = self._main_args.local

        self._cleanup_files: Sequence[Path] = []
        self._remote_action = self._setup_remote_action()

    @property
    def local_command(self) -> Sequence[str]:
        return self._local_command

    @property
    def remote_command(self) -> Sequence[str]:
        local_tool = self.local_tool
        return [
            self.remote_tool if tok == local_tool else tok
            for tok in self._local_command
        ]

    def check_preconditions(self):
        # check for required remote tools
        tool = self.remote_tool
        if not tool.exists():
            raise RuntimeError(
                f"Missing the following tools for remote execution: {tool}.  See tqr/563535 for how to fetch the needed packages."
            )

    @property
    def command_line_inputs(self) -> Sequence[Path]:
        return [
            Path(p) for p in cl_utils.flatten_comma_list(self._main_args.inputs)
        ]

    @property
    def command_line_inputs_lists(self) -> Sequence[Path]:
        return [
            Path(p)
            for p in cl_utils.flatten_comma_list(
                self._main_args.input_list_paths
            )
        ]

    @property
    def command_line_output_files(self) -> Sequence[Path]:
        return [
            Path(p)
            for p in cl_utils.flatten_comma_list(self._main_args.output_files)
        ]

    @property
    def command_line_output_dirs(self) -> Sequence[Path]:
        return [
            Path(p)
            for p in cl_utils.flatten_comma_list(
                self._main_args.output_directories
            )
        ]

    def prepare(self):
        """Setup everything ahead of remote execution.

        Raises:
          RuntimeError exception if pre-flight requirements are not met.
        """
        assert (
            not self.local_only
        ), "This should not be reached in local-only mode."

        self.check_preconditions()

    def _setup_remote_action(self) -> remote_action.RemoteAction:
        tool_name = self.label_toolname.name
        remote_options = [
            # type=tool says we are providing a custom tool, and thus,
            #   own the logic for providing explicit inputs.
            # shallow=true works around an issue where racing mode downloads
            #   incorrectly
            # toolname self-identifies the action type for metrics
            f"--labels=type=tool,shallow=true,toolname={tool_name}",
            # --canonicalize_working_dir: coerce the output dir to a constant.
            #   This requires that the command be insensitive to output dir, and
            #   that its outputs do not leak the remote output dir.
            #   Ensuring that the results reproduce consistently across different
            #   build directories helps with caching.
            "--canonicalize_working_dir=true",
        ] + self._main_remote_options  # allow forwarded options to override defaults

        # Automatically add the tool.
        remote_inputs = [self.remote_tool]

        action = remote_action.remote_action_from_args(
            main_args=self._main_args,  # includes inputs and outputs already
            remote_options=remote_options,
            command=self.remote_command,
            inputs=remote_inputs,
            working_dir=self.working_dir,
            exec_root=self.exec_root,
        )
        self.vprintlist("remote inputs", action.inputs_relative_to_project_root)
        self.vprintlist(
            "remote output files", action.output_files_relative_to_project_root
        )
        self.vprintlist(
            "remote output dirs", action.output_dirs_relative_to_project_root
        )
        self.vprintlist("rewrapper options", remote_options)
        return action

    @property
    def remote_action(self) -> remote_action.RemoteAction:
        return self._remote_action

    @property
    def working_dir(self) -> Path:
        return self._working_dir

    @property
    def exec_root(self) -> Path:
        return self._exec_root

    @property
    def exec_root_rel(self) -> Path:
        return cl_utils.relpath(self.exec_root, start=self.working_dir)

    @property
    def host_platform(self) -> str:
        return self._host_platform

    @property
    def verbose(self) -> bool:
        return self._main_args.verbose

    @property
    def dry_run(self) -> bool:
        return self._main_args.dry_run

    def vmsg(self, text: str):
        if self.verbose:
            msg(text)

    def vprintlist(self, desc: str, items: Iterable[Any]):
        """In verbose mode, print elements.

        Args:
          desc: text description of what is being printed.
          items: stream of any type of object that is str-able.
        """
        if self.verbose:
            msg(f"{desc}: {{")
            for item in items:
                text = str(item)
                print(f"  {text}")
            print(f"}}  # {desc}")

    @property
    def local_only(self) -> bool:
        return self._local_only

    @property
    def local_tool(self) -> Optional[Path]:
        for tok in self.local_command:
            if "=" not in tok:
                return Path(tok)

    @property
    def label_toolname(self) -> Path:
        return self._main_args.label_toolname or self.local_tool

    @property
    def remote_tool(self) -> Optional[Path]:
        # selects the binary for the remote execution platform
        return fuchsia.remote_executable(self.local_tool)

    def _run_locally(self) -> int:
        return subprocess.call(
            cl_utils.auto_env_prefix_command(self.local_command)
        )

    def _run_remote_action(self) -> int:
        return self.remote_action.run_with_main_args(self._main_args)

    def run(self) -> int:
        if self.local_only:
            return self._run_locally()

        self.prepare()

        try:
            return self._run_remote_action()
        finally:
            if not self._main_args.save_temps:
                self._cleanup()

    def _cleanup(self):
        for f in self._cleanup_files:
            f.unlink()


def main(argv: Sequence[str]) -> int:
    action = PrebuiltToolAction(
        argv,  # [remote options] -- command...
        exec_root=remote_action.PROJECT_ROOT,
        working_dir=Path(os.curdir),
        host_platform=fuchsia.HOST_PREBUILT_PLATFORM,
    )
    return action.run()


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
