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

# Pylint is not smart enough to infer the return type of methods with a custom
# property decorator like @cached_property, so we have to disable some spurious
# warnings from cached property accesses. See
# https://github.com/PyCQA/pylint/issues/3484
#
# pylint: disable=no-member, not-an-iterable, not-context-manager
# pylint: disable=unsubscriptable-object

import copy
import difflib

import attr
from google.protobuf import json_format as jsonpb

from recipe_engine import recipe_api

from .orchestration_inputs import _TestOrchestrationInputs

from PB.go.fuchsia.dev.fuchsia.tools.integration.fint.proto import (
    context as context_pb2,
    set_artifacts as fint_set_artifacts_pb2,
    build_artifacts as fint_build_artifacts_pb2,
)

from RECIPE_MODULES.fuchsia.utils import cached_property, memoize

# `fint set` and `fint build`, respectively, will write these files to the
# artifact directory specified by the context spec.
FINT_SET_ARTIFACTS = "set_artifacts.json"
FINT_BUILD_ARTIFACTS = "build_artifacts.json"

# Manifests produced by the build.
CTS_ARTIFACTS_JSON = "cts_artifacts.json"
RBE_CONFIG_JSON = "rbe_config.json"
TOOL_PATHS_JSON = "tool_paths.json"
TRIAGE_SOURCES_JSON = "triage_sources.json"

# Name of BigQuery project and table for uploading artifacts.
BIGQUERY_PROJECT = "fuchsia-infra"
BIGQUERY_ARTIFACTS_DATASET = "artifacts"

# The private and authorized SSH keys pulled down in the checkout, relative to
# the fuchsia root.
CHECKOUT_AUTHORIZED_KEY = ".ssh/authorized_keys"
CHECKOUT_PRIVATE_KEY = ".ssh/pkey"

# The path to a public key used to sign release builds. Only set on release
# builders.
RELEASE_PUBKEY_PATH = "/etc/release_keys/release_key_pub.pem"

# The name of the public key file uploaded in release builds.
RELEASE_PUBKEY_FILENAME = "publickey.pem"

# Name of compdb generated by GN, it is expected in the root of the build
# directory.
GN_COMPDB_FILENAME = "compile_commands.json"

# Name of the log containing the build failure summary.
FAILURE_SUMMARY_LOG = "failure summary"

# Set as an output property and consumed by the
# go/cq-incremental-builder-monitor_dev dashboard.
BUILD_FAILED_PROPERTY = "build_failed"


class NoSuchTool(Exception):
    def __init__(self, name, cpu, os):
        super(NoSuchTool, self).__init__(
            "no such tool in %s: (name=%r, cpu=%r, os=%r)"
            % (TOOL_PATHS_JSON, name, cpu, os)
        )


@attr.s
class _FuchsiaBuildResults(object):
    """Represents a completed build of Fuchsia.

    Attributes:
        archives: Mapping between the canonical name of an archive produced by the Fuchsia
            build to the absolute path to that archive on the local disk.
        checkout: The Fuchsia checkout.
        build_dir: The directory where Fuchsia build artifacts may be found.
        images: Mapping between the canonical name of an image produced by the Fuchsia
            build to its path relative to the fuchsia build directory.
        gn_results: GN gen step results
    """

    _api = attr.ib()
    checkout = attr.ib()
    build_dir = attr.ib()
    gn_results = attr.ib()
    images = attr.ib(factory=list)
    archives = attr.ib(factory=list)
    _size_check_failed = attr.ib(init=False, default=False)
    ninja_targets = attr.ib(factory=list)
    zedboot_images = attr.ib(factory=list)
    zbi_test_qemu_kernel_images = attr.ib(factory=dict)
    fint_build_artifacts = attr.ib(
        type=fint_build_artifacts_pb2.BuildArtifacts, default=None
    )

    def __deepcopy__(self, memodict):
        # Shallow copy first.
        new = copy.copy(self)
        # Only images needs to be a real deep copy.
        new.images = copy.deepcopy(new.images, memodict)
        return new

    @property
    def set_metadata(self):
        return self.gn_results.fint_set_artifacts.metadata

    @property
    def affected_tests(self):
        """Returns a list of names of tests affected by the current gerrit change."""
        if self._api.build.can_exit_early_if_unaffected(self.checkout):
            return self.fint_build_artifacts.affected_tests
        return []

    @property
    def no_work(self):
        """Returns whether all testing can be skipped."""
        if self._api.build.can_exit_early_if_unaffected(self.checkout):
            return self.fint_build_artifacts.build_not_affected
        return False

    @property
    def authorized_key(self):
        return self.checkout.root_dir.join(CHECKOUT_AUTHORIZED_KEY)

    @property
    def private_key(self):
        return self.checkout.root_dir.join(CHECKOUT_PRIVATE_KEY)

    @cached_property
    def _binary_sizes(self):
        """The binary sizes data produced by the build.

        Returns:
            Tuple of (sizes dict, stdout str).
        """
        cmd = [
            self.tool("size_checker"),
            "--build-dir",
            self.build_dir,
            "--sizes-json-out",
            self._api.json.output(),
        ]
        check_sizes_result = self._api.step(
            "size_checker",
            cmd,
            step_test_data=lambda: self._api.json.test_api.output({"component": 1}),
            ok_ret="any",
            stderr=self._api.raw_io.output(),
        )
        self._size_check_failed = bool(check_sizes_result.exc_result.retcode)
        return check_sizes_result.json.output, check_sizes_result.stderr

    @cached_property
    def cts_artifacts(self):
        """The paths to CTS artifacts relative to the checkout root."""
        relpaths = self._api.file.read_json(
            "read cts artifacts manifest",
            self.build_dir.join(CTS_ARTIFACTS_JSON),
            test_data=["foo.far", "bar.far"],
        )
        return [
            self._api.path.abs_to_path(
                self._api.path.realpath(self.build_dir.join(relpath))
            )
            for relpath in relpaths
        ]

    @cached_property
    def generated_sources(self):
        """The paths to the generated source files relative to the checkout root."""
        generated_sources = []
        for path in self.gn_results.generated_sources:
            try:
                abspath = self._api.path.abs_to_path(
                    self._api.path.realpath(self.build_dir.join(path.lstrip("/")))
                )
            except ValueError:  # pragma: no cover
                raise self._api.step.StepFailure(
                    "Invalid path in generated_sources.json: %s" % path
                )
            self._api.path.mock_add_paths(abspath)
            if self._api.path.exists(abspath):
                generated_sources.append(
                    self._api.path.relpath(abspath, self.checkout.root_dir)
                )
        return generated_sources

    @cached_property
    def triage_sources(self):
        """The paths to the triage sources relative to the checkout root."""
        return [
            self._api.path.relpath(f, self.checkout.root_dir)
            for f in self.gn_results.triage_sources
        ]

    @property
    def compdb_path(self):
        return self.gn_results.compdb_path

    def filtered_compdb(self, *args, **kwargs):
        return self.gn_results.filtered_compdb(*args, **kwargs)

    def tool(self, name, cpu="x64", os=None, **kwargs):
        """The path to a tool of the given name and cpu."""
        return self.gn_results.tool(name, cpu, os, **kwargs)

    def check_binary_sizes(self):
        """Checks that binary sizes are less than the maximum allowed.

        Raises:
          StepFailure if the size exceeds the maximum.
        """
        # This property is read by the binary-size Gerrit plugin.
        with self._api.step.nest("check binary sizes") as presentation:
            sizes_json, size_checker_logs = self._binary_sizes
            presentation.logs["size_checker logs"] = size_checker_logs
            if sizes_json:
                presentation.properties["binary_sizes"] = sizes_json
            if self._size_check_failed:
                presentation.logs["size_checker JSON output"] = sizes_json
                raise self._api.step.StepFailure("binary size checks failed")

    def upload(self, gcs_bucket, is_release_version=False, namespace=None):
        """Uploads artifacts from the build to Google Cloud Storage.

        Args:
          gcs_bucket (str): GCS bucket name to upload build results to.
          is_release_version (bool): True if checkout is a release version.
          namespace (str|None): A unique namespace for the GCS upload location;
            if None, the current build's ID is used.
        """
        assert gcs_bucket
        with self._api.step.nest("upload build results"):
            self._api.build._upload_build_results(
                self, gcs_bucket, is_release_version, namespace
            )
        self._api.build._upload_package_snapshot(self, gcs_bucket, namespace)

    def upload_tracing_data(self, gcs_bucket, namespace):
        """Uploads GN and ninja tracing results for this build to GCS.

        Args:
          gcs_bucket (str): GCS bucket name to upload build results to.
          namespace (str|None): A unique namespace for the GCS upload location;
            if None, the current build's ID is used.
        """
        assert gcs_bucket
        self._api.build._upload_tracing_data(self, gcs_bucket, namespace)


@attr.s(frozen=True)
class _GNResults(object):
    """_GNResults represents the result of a `gn gen` invocation in the fuchsia build.

    It exposes the API of the build, which defines how one can invoke
    ninja.
    """

    _api = attr.ib()
    build_dir = attr.ib()
    fint_set_artifacts = attr.ib(
        # Optional for convenience when writing tests. Production recipe code
        # should always populate this field.
        default=None,
        # Proto objects are not hashable.
        hash=False,
    )
    _compdb_cache = attr.ib(factory=dict, init=False)
    # The following attributes are private because they are only intended to be
    # used from within this recipe module, not by any recipes that use this
    # recipe module.
    _fint_path = attr.ib(default=None)
    _fint_params_path = attr.ib(default=None)
    _fint_context = attr.ib(default=None)

    def __attrs_post_init__(self):
        # Eagerly read in the tools manifest so that it always has the same
        # step name regardless of when the caller first accesses the manifest.
        self._tools  # pylint: disable=pointless-statement

    @property
    def skip_build(self):
        """Whether it's safe to skip doing a full build."""
        return self.fint_set_artifacts.skip_build

    @property
    def gn_trace_path(self):
        """The path to a GN trace file produced by `fint set`."""
        return self.fint_set_artifacts.gn_trace_path

    @cached_property
    def generated_sources(self):
        """Returns the generated source files (list(str)) from the fuchsia build.

        The returned paths are relative to the fuchsia build directory.
        """
        return self._api.file.read_json(
            "read generated sources",
            self.build_dir.join("generated_sources.json"),
            test_data=["generated_header.h"],
        )

    def tool(self, name, cpu="x64", os=None, mock_for_tests=True):
        """Returns the path to the specified tool provided from the tool_paths
        manifest.

        Args:
            name (str): The short name of the tool, as it appears in
                tool_paths.json (usually the same as the basename of the
                executable).
            cpu (str): The arch of the machine the tool will run on.
            os (str): The OS of the machine the tool will run on.
            mock_for_tests (bool): Whether to mock the tool info if it's not
                found in tool_paths.json. Ignored in production, only
                useful in recipe unit test mode for getting code coverage of
                the missing tool code path.
        """
        os = os or self._api.platform.name
        try:
            tool = self._tools[name, cpu, os]
        except KeyError:
            # If we're in recipe unit testing mode, just return some mock info
            # for the tool if it's not in tool_paths.json. Requiring that every
            # tool used by the recipe shows up in the mock tool_paths.json is a
            # maintenance burden, since adding a dependency on a new tool also
            # requires modifying the mock tool_paths.json. It would also
            # create much more noise in expectation files.
            if self._api.build._test_data.enabled and mock_for_tests:
                tool = {"path": "%s_%s/%s" % (os, cpu, name)}
            else:
                raise NoSuchTool(name, cpu, os)

        relpath = tool["path"]
        try:
            return self._api.path.abs_to_path(
                self._api.path.realpath(self.build_dir.join(relpath))
            )
        except ValueError:  # pragma: no cover
            raise self._api.step.StepFailure(
                "Invalid path in tool_paths.json: %s" % relpath
            )

    @cached_property
    def _tools(self):
        tools = {}
        tool_paths_manifest = self._api.file.read_json(
            "read tool_paths manifest",
            self.build_dir.join(TOOL_PATHS_JSON),
            test_data=[
                {"name": "foo", "cpu": "x64", "os": "linux", "path": "linux_x64/foo"}
            ],
        )
        for tool in tool_paths_manifest:
            key = (tool["name"], tool["cpu"], tool["os"])
            assert key not in tools, (
                "only one tool with (name, cpu, os) == (%s, %s, %s) is allowed" % key
            )
            tools[key] = tool
        return tools

    @cached_property
    def triage_sources(self):
        """Returns the absolute paths of the files defined in the triage_sources
        manifest."""
        triage_sources_manifest = self._api.file.read_json(
            "read triage_sources manifest",
            self.build_dir.join(TRIAGE_SOURCES_JSON),
            test_data=self._api.build.test_api.mock_triage_sources_manifest(),
        )
        return [
            self._api.path.abs_to_path(
                self._api.path.realpath(self.build_dir.join(source))
            )
            for source in triage_sources_manifest
        ]

    @cached_property
    def rbe_config_path(self):
        """Returns the checkout relative path to the RBE config specified in
        the Fuchsia source tree."""
        rbe_config_manifest = self._api.file.read_json(
            "read rbe_config manifest",
            self.build_dir.join(RBE_CONFIG_JSON),
            test_data=[{"path": "../../path/to/rbe/config.cfg"}],
        )
        assert len(rbe_config_manifest) == 1
        rbe_config_path = self._api.path.abs_to_path(
            self._api.path.realpath(self.build_dir.join(rbe_config_manifest[0]["path"]))
        )
        return rbe_config_path

    @property
    def compdb_path(self):
        return self.build_dir.join(GN_COMPDB_FILENAME)

    def filtered_compdb(self, filters=()):
        """The path to a merged compilation database, filtered via the passed
        filters."""
        filters = tuple(filters)  # Ensure hashability.
        if filters not in self._compdb_cache:
            self._compdb_cache[filters] = self._filtered_compdb(filters)
        return self._compdb_cache[filters]

    def _filtered_compdb(self, filters):
        def keep_in_compdb(entry):
            # Filenames are relative to the build directory, and the build
            # directory is absolute.
            build_dir = self._api.path.abs_to_path(entry["directory"])
            abspath = self._api.path.realpath(
                self._api.path.join(build_dir, entry["file"])
            )
            try:
                path = self._api.path.abs_to_path(abspath)
            except ValueError:
                # This happens if `abspath` is not rooted in one of the path
                # module's known paths, which is the case for paths in `/bin`,
                # for example. That also implies that the path isn't in the
                # build directory, so skip it.
                return False

            if build_dir.is_parent_of(path):
                return False

            segments = entry["file"].split(self._api.path.sep)
            if any(bad_segments in segments for bad_segments in filters):
                return False
            return True

        compdb_filtered = [entry for entry in self._compdb if keep_in_compdb(entry)]
        compdb_path = self._api.path["cleanup"].join(GN_COMPDB_FILENAME)
        self._api.file.write_json(
            "write filtered compdb",
            compdb_path,
            compdb_filtered,
            # This file is generally massive, so we don't want to upload it to
            # Logdog because that would take ages.
            include_log=False,
        )
        return compdb_path

    @cached_property
    def _compdb(self):
        # Assumes that the current builder is configured to generate compdbs.
        return self._api.file.read_json(
            "read compdb",
            self.compdb_path,
            test_data=[
                {
                    "directory": "[START_DIR]/out/not-default",
                    "file": "../../foo.cpp",
                    "command": "clang++ foo.cpp",
                },
                {
                    "directory": "[START_DIR]/out/not-default",
                    "file": "../../third_party/foo.cpp",
                    "command": "clang++ third_party/foo.cpp",
                },
                {
                    "directory": "[START_DIR]/out/not-default",
                    "file": "../../out/not-default/foo.cpp",
                    "command": "clang++ foo.cpp",
                },
                {
                    "directory": "[START_DIR]/out/not-default",
                    "file": "/bin/ln",
                    "command": "/bin/ln -s foo bar",
                },
            ],
            include_log=False,
        )

    @cached_property
    def zbi_tests(self):
        """Returns the ZBI tests from the Fuchsia build directory."""
        return self._api.file.read_json(
            "read zbi test manifest",
            self.build_dir.join("zbi_tests.json"),
            test_data=[],
        )


class FuchsiaBuildApi(recipe_api.RecipeApi):
    """APIs for building Fuchsia."""

    FINT_PARAMS_PROPERTY = "fint_params"
    FINT_PARAMS_PATH_PROPERTY = "fint_params_path"
    NoSuchTool = NoSuchTool

    def __init__(self, props, *args, **kwargs):
        super(FuchsiaBuildApi, self).__init__(*args, **kwargs)
        self._clang_toolchain = props.clang_toolchain
        self._clang_toolchain_dir = ""
        self._gcc_toolchain = props.gcc_toolchain
        self._gcc_toolchain_dir = ""
        self._rust_toolchain = props.rust_toolchain
        self._rust_toolchain_dir = ""
        self._emitted_ninja_duration = False

    @property
    def clang_toolchain_dir(self):
        if not self._clang_toolchain_dir and self._clang_toolchain.version:
            self._clang_toolchain_dir = self._download_toolchain(
                "clang", self._clang_toolchain, "third_party/clang"
            )
        return self._clang_toolchain_dir

    @clang_toolchain_dir.setter
    def clang_toolchain_dir(self, value):
        self._clang_toolchain_dir = value

    @property
    def gcc_toolchain_dir(self):
        if not self._gcc_toolchain_dir and self._gcc_toolchain.version:
            self._gcc_toolchain_dir = self._download_toolchain(
                "gcc", self._gcc_toolchain, "third_party/gcc"
            )
        return self._gcc_toolchain_dir

    @gcc_toolchain_dir.setter
    def gcc_toolchain_dir(self, value):
        self._gcc_toolchain_dir = value

    @property
    def rust_toolchain_dir(self):
        if not self._rust_toolchain_dir and self._rust_toolchain.version:
            self._rust_toolchain_dir = self._download_toolchain(
                "rust", self._rust_toolchain, "third_party/rust"
            )
        return self._rust_toolchain_dir

    @rust_toolchain_dir.setter
    def rust_toolchain_dir(self, value):
        self._rust_toolchain_dir = value

    def with_options(
        self,
        checkout,
        fint_params_path,
        build_dir=None,
        collect_coverage=False,
        incremental=False,
        sdk_id=None,
        **kwargs
    ):
        """Builds Fuchsia from a Jiri checkout.

        Depending on the fint parameters, may or may not build
        Fuchsia-the-operating-system (i.e. the Fuchsia images).

        Args:
            checkout (CheckoutResult): The Fuchsia checkout result.
            fint_params_path (str): The path, relative to the checkout root,
                of a platform spec textproto to pass to fint.
            build_dir (Path): The build output directory.
            collect_coverage (bool): Whether to build for collecting
                coverage.
            incremental (bool): Whether or not to build incrementally.
            sdk_id (str): If specified, set sdk_id in GN.
            **kwargs (dict): Passed through to _build().

        Returns:
            A FuchsiaBuildResults, representing the build.
        """
        with self.m.step.nest("build") as presentation, self.m.macos_sdk():
            fint_params = self.m.file.read_text(
                "read fint params",
                checkout.root_dir.join(fint_params_path),
                test_data='field: "value"',
            )
            presentation.logs["fint_params"] = fint_params
            # Write the fint params file to output properties so it can be
            # logged by the orchestrator build if we're running in subbuild
            # mode.
            presentation.properties[self.FINT_PARAMS_PROPERTY] = fint_params
            # Write the fint params path to output properties so `fx repro`
            # knows which file to use.
            presentation.properties[self.FINT_PARAMS_PATH_PROPERTY] = fint_params_path

            gn_results = self.gen(
                checkout=checkout,
                fint_params_path=fint_params_path,
                build_dir=build_dir,
                sdk_id=sdk_id,
                collect_coverage=collect_coverage,
                presentation=presentation,
            )

            # Upload tests.json to Logdog so it's available to aid in debugging.
            self.m.file.read_text(
                "read tests.json", gn_results.build_dir.join("tests.json")
            )

            if self.can_exit_early_if_unaffected(checkout) and gn_results.skip_build:
                return None

            return self._build(
                checkout=checkout,
                gn_results=gn_results,
                presentation=presentation,
                **kwargs
            )

    def gen(
        self,
        checkout,
        fint_params_path,
        build_dir=None,
        sdk_id=None,
        collect_coverage=False,
        presentation=None,
    ):
        """Sets up and calls `gn gen`.

        Args:
            checkout (CheckoutApi.CheckoutResults): The checkout results.
            fint_params_path (str): The path to a build params textproto to
                pass to fint, relative to the checkout directory.
            build_dir (Path): The build directory. This defaults to "out/not-default".
                Note that changing the build dir will invalidate Goma caches so ideally
                should be only used when Goma is disabled.
            sdk_id (str): The current SDK ID
            collect_coverage (bool): Whether to build for collecting coverage.
            presentation (StepPresentation): Step to attach logs to.

        Returns:
            A _GNResults object.
        """
        assert fint_params_path, "fint_params_path must be set"

        if not build_dir:
            # Some parts of the build require the build dir to be two
            # directories nested underneath the checkout dir.
            # We choose the path to be intentionally different from
            # "out/default" because that is what most developers use locally and we
            # want to prevent the build from relying on those directory names.
            build_dir = checkout.root_dir.join("out", "not-default")

        # with_options() normally handles setting up the macOS SDK, but we need
        # to ensure it's set up here to support recipes that call `gen()`
        # directly.
        with self.m.macos_sdk(), self.m.context(cwd=checkout.root_dir):
            context = self._fint_context(
                checkout=checkout,
                build_dir=build_dir,
                sdk_id=sdk_id,
                collect_coverage=collect_coverage,
            )
            fint_path = self._fint_path(checkout)
            # We call this step `gn gen` even though it runs `fint set`
            # to avoid confusion about when the recipe runs `gn gen`.
            step = self._run_fint(
                "gn gen",
                "set",
                fint_path,
                checkout.root_dir.join(fint_params_path),
                context,
            )

            # Artifacts should be produced even if some `fint set` steps
            # failed, as the artifacts may contain useful logs.
            artifacts = self.m.file.read_proto(
                "read fint set artifacts",
                self.m.path.join(context.artifact_dir, FINT_SET_ARTIFACTS),
                fint_set_artifacts_pb2.SetArtifacts,
                "JSONPB",
                test_proto=fint_set_artifacts_pb2.SetArtifacts(
                    gn_trace_path=self.m.path.join(
                        context.artifact_dir, "mock-gn-trace.json"
                    ),
                    use_goma=True,
                    enable_rbe=True,
                    metadata=dict(
                        board="boards/x64.gni",
                        optimize="debug",
                        product="products/core.gni",
                        target_arch="x64",
                        variants=["asan"],
                    ),
                ),
            )

            # Log the full failure summary so the entire text is visible even if
            # it's truncated in the summary markdown.
            if artifacts.failure_summary and presentation:
                presentation.logs[
                    FAILURE_SUMMARY_LOG
                ] = artifacts.failure_summary.splitlines()

            if step.retcode:
                if artifacts.failure_summary:
                    msg = self.m.buildbucket_util.summary_message(
                        artifacts.failure_summary,
                        "(failure summary truncated, see the '%s' log for "
                        "full failure details)" % FAILURE_SUMMARY_LOG,
                    )
                else:
                    msg = "Unrecognized fint set failure, see stdout for details"
                raise self.m.step.StepFailure(msg)
            elif artifacts.failure_summary:
                raise self.m.step.StepFailure(
                    "`fint set` emitted a failure summary but had a retcode of zero"
                )

            return self.gn_results(
                build_dir,
                artifacts,
                fint_path=fint_path,
                fint_params_path=checkout.root_dir.join(fint_params_path),
                fint_context=context,
            )

    def _build(
        self,
        checkout,
        gn_results,
        presentation,
        allow_dirty=False,
        gcs_bucket=None,
        stats_gcs_bucket=None,
        upload_namespace=None,
        timeout_secs=90 * 60,
    ):
        """Runs `fint build`.

        Fint build consumes the GN build APIs from the build directory as
        well as the fint params path to determine what targets to build.

        Args:
            checkout (CheckoutResult): The Fuchsia checkout result.
            gn_results (_GNResults): GN gen results.
            presentation (StepPresentation): Presentation to attach important
                logs to.
            allow_dirty (bool): Skip the ninja no op check.
            gcs_bucket (str or None): A GCS bucket to upload crash reports
                to.
            stats_gcs_bucket (str): GCS bucket name to upload build stats to.
            timeout_secs (str): The timeout for running `fint build`.
            upload_namespace (str): The namespace within the build stats GCS
                bucket to upload to.

        Returns:
            A FuchsiaBuildResults, representing the build.
        """
        if gn_results.fint_set_artifacts.use_goma:
            self.m.goma.set_path(self.m.path.dirname(gn_results.tool("goma_ctl")))
            goma_context = self.m.goma.build_with_goma
        else:
            goma_context = self.m.nullcontext

        if gn_results.fint_set_artifacts.enable_rbe:
            self.m.rbe.set_path(
                self.m.path.abs_to_path(
                    self.m.path.dirname(gn_results.tool("rewrapper"))
                )
            )
            self.m.rbe.set_config_path(gn_results.rbe_config_path)
            rbe_context = self.m.rbe
        else:
            rbe_context = self.m.nullcontext

        context = copy.deepcopy(gn_results._fint_context)
        context.skip_ninja_noop_check = allow_dirty

        with goma_context(), rbe_context():
            fint_build_step = self._run_fint(
                step_name="ninja",
                command="build",
                fint_path=gn_results._fint_path,
                static_path=gn_results._fint_params_path,
                context=context,
                timeout=timeout_secs,
            )

        # Artifacts should be produced even if some `fint build` steps failed,
        # as the artifacts may contain useful logs that will help understand
        # the cause of failure.
        fint_build_artifacts = self.m.file.read_proto(
            "read fint build artifacts",
            self.m.path.join(context.artifact_dir, FINT_BUILD_ARTIFACTS),
            fint_build_artifacts_pb2.BuildArtifacts,
            "JSONPB",
            test_proto=self.test_api.fint_build_artifacts_proto(
                # This isn't super realistic because tests sometimes aren't
                # included in the build graph, in which case there would never
                # be any affected tests even in CQ with changed files. But it's
                # simplest if we just configure the mock affected tests here.
                affected_tests=["test1", "test2"] if checkout.changed_files() else [],
                built_targets=["target1", "target2"],
                built_images=[{"name": "foo", "type": "blk", "path": "foo.img"}],
            ),
        )

        # Log the full failure summary so the entire text is visible even if
        # it's truncated in the summary markdown.
        if fint_build_artifacts.failure_summary:
            presentation.logs[
                FAILURE_SUMMARY_LOG
            ] = fint_build_artifacts.failure_summary.splitlines()

        if fint_build_artifacts.log_files:
            with self.m.step.nest("read fint log files"):
                for name, path in fint_build_artifacts.log_files.items():
                    presentation.logs[name] = self.m.file.read_text(
                        "read %s" % self.m.path.basename(path), path, include_log=False
                    ).splitlines()

        # Only emit the ninja duration once even if we build multiple times.
        # The builders for which we care about tracking the Ninja duration all
        # only build once. For builders like perfcompare that build twice,
        # the second build is incremental, so it is very fast and its duration
        # is less meaningful than the original build's duration.
        if not self._emitted_ninja_duration:
            presentation.properties[
                "ninja_duration_seconds"
            ] = fint_build_artifacts.ninja_duration_seconds
            self._emitted_ninja_duration = True

        if stats_gcs_bucket and upload_namespace:
            try:
                self._upload_buildstats_output(
                    gn_results, stats_gcs_bucket, upload_namespace, fint_build_artifacts
                )
            except Exception as e:
                self.m.step("upload buildstats failure", None).presentation.logs[
                    "exception"
                ] = str(e).splitlines()

        if fint_build_step.retcode:
            if fint_build_artifacts.failure_summary:
                msg = self.m.buildbucket_util.summary_message(
                    fint_build_artifacts.failure_summary,
                    "(failure summary truncated, see the '%s' log for "
                    "full failure details)" % FAILURE_SUMMARY_LOG,
                )
            else:
                msg = "Unrecognized fint build failure, see stdout for details"

            with self.m.step.nest("clang-crashreports"), self.m.context(
                infra_steps=True
            ):
                self._upload_crash_report(
                    gn_results.build_dir, gcs_bucket, self.m.buildbucket.build.id
                )

            raise self.m.step.StepFailure(msg)
        elif fint_build_artifacts.failure_summary:
            raise self.m.step.StepFailure(
                "`fint build` emitted a failure summary but had a retcode of zero"
            )

        # Recursively convert to a dict so that we don't have to deal with
        # proto Struct objects, which have some annoying properties like
        # not showing the missing key value when raising a KeyError.
        artifacts_dict = jsonpb.MessageToDict(
            fint_build_artifacts,
            including_default_value_fields=True,
            preserving_proto_field_name=True,
        )

        return self.build_results(
            build_dir=gn_results.build_dir,
            checkout=checkout,
            gn_results=gn_results,
            images=artifacts_dict["built_images"],
            archives=artifacts_dict["built_archives"],
            ninja_targets=artifacts_dict["built_targets"],
            zedboot_images=artifacts_dict["built_zedboot_images"],
            zbi_test_qemu_kernel_images=artifacts_dict["zbi_test_qemu_kernel_images"],
            fint_build_artifacts=fint_build_artifacts,
        )

    def can_exit_early_if_unaffected(self, checkout):
        """Returns whether or not we can safely skip building (and testing)."""
        return (
            # No changed_files -> CI, which we always want to test. fint should
            # also take this into account and never indicate that testing can be
            # skipped if there are no changed files, but we add an extra check
            # here to be safe.
            checkout.changed_files()
            # Changes to integration, in particular for both infra configs and
            # jiri manifests, can affect any stage of the build but generally
            # won't cause changes to the build graph.
            and not checkout.contains_integration_patch
            # Recipe changes can also impact all stages of a build, but recipes
            # aren't included in the build graph.
            and not self.m.recipe_testing.enabled
        )

    def gn_results(self, *args, **kwargs):
        return _GNResults(self.m, *args, **kwargs)

    def build_results(self, *args, **kwargs):
        return _FuchsiaBuildResults(self.m, *args, **kwargs)

    def download_test_orchestration_inputs(self, digest):
        return _TestOrchestrationInputs.download(self.m, digest)

    def test_orchestration_inputs_from_build_results(self, *args, **kwargs):
        return _TestOrchestrationInputs.from_build_results(self.m, *args, **kwargs)

    def test_orchestration_inputs_property_name(self, without_cl):
        if without_cl:
            return _TestOrchestrationInputs.DIGEST_PROPERTY_WITHOUT_CL
        else:
            return _TestOrchestrationInputs.DIGEST_PROPERTY

    @memoize
    def _fint_context(self, checkout, build_dir, sdk_id, collect_coverage):
        """Assembles a fint Context spec."""
        return context_pb2.Context(
            checkout_dir=str(checkout.root_dir),
            build_dir=str(build_dir),
            artifact_dir=str(self.m.path.mkdtemp("fint_artifacts")),
            sdk_id=sdk_id or "",
            changed_files=[
                context_pb2.Context.ChangedFile(
                    path=self.m.path.relpath(path, checkout.root_dir)
                )
                for path in checkout.changed_files()
            ],
            cache_dir=str(self.m.path["cache"]),
            release_version=checkout.release_version,
            clang_toolchain_dir=str(self.clang_toolchain_dir),
            gcc_toolchain_dir=str(self.gcc_toolchain_dir),
            rust_toolchain_dir=str(self.rust_toolchain_dir),
            collect_coverage=collect_coverage,
            goma_job_count=self.m.goma.jobs,
        )

    @memoize
    def _fint_path(self, checkout):
        """Builds and returns the path to a fint executable."""
        # TODO(olivernewman): Rebuild fint if the checkout hash changes (e.g.
        # for perfcompare).
        fint_path = self.m.path.mkdtemp("fint").join("fint")
        bootstrap_path = checkout.root_dir.join("tools", "integration", "bootstrap.sh")
        self.m.step("bootstrap fint", [bootstrap_path, "-o", fint_path])
        return fint_path

    def _run_fint(
        self,
        step_name,
        command,
        fint_path,
        static_path,
        context,
        timeout=None,
        **kwargs
    ):
        context_textproto = self.m.proto.encode(context, "TEXTPB")
        step = self.m.step(
            step_name,
            [
                fint_path,
                command,
                "-static",
                static_path,
                "-context",
                self.m.raw_io.input(context_textproto),
            ],
            ok_ret="any",
            timeout=timeout,
            **kwargs
        )
        if step.retcode or step.exc_result.had_timeout:
            step.presentation.status = self.m.step.FAILURE
            step.presentation.properties[BUILD_FAILED_PROPERTY] = True
        step.presentation.step_text = "run by `fint %s`" % command
        step.presentation.logs["context.textproto"] = context_textproto
        if step.exc_result.had_timeout:
            timeout_string = "%d seconds" % timeout
            if timeout > 60:
                timeout_string = "%d minutes" % (timeout / 60)
            raise self.m.step.StepFailure(
                "`%s` timed out after %s." % (step_name, timeout_string)
            )
        return step

    def _upload_crash_report(self, build_dir, gcs_bucket, build_id):
        crashreports_dir = build_dir.join("clang-crashreports")
        self.m.path.mock_add_paths(crashreports_dir)
        if not gcs_bucket or not self.m.path.exists(crashreports_dir):
            return  # pragma: no cover
        temp = self.m.path.mkdtemp("reproducers")
        reproducers = self.m.file.glob_paths(
            "find reproducers",
            crashreports_dir,
            "*.sh",
            test_data=[crashreports_dir.join("foo.sh")],
        )
        for reproducer in reproducers:
            base = self.m.path.splitext(self.m.path.basename(reproducer))[0]
            files = self.m.file.glob_paths(
                "find %s files" % base,
                crashreports_dir,
                base + ".*",
                test_data=[
                    crashreports_dir.join("foo.sh"),
                    crashreports_dir.join("foo.cpp"),
                ],
            )
            tgz_basename = "%s.tar.gz" % base
            tgz_path = temp.join(tgz_basename)
            archive = self.m.tar.create(tgz_path, compression="gzip")
            for f in files:
                archive.add(f, crashreports_dir)
            archive.tar("create %s" % tgz_basename)
            self.m.upload.file_to_gcs(
                source=tgz_path,
                bucket=gcs_bucket,
                subpath=tgz_basename,
                namespace=build_id,
            )

    def _upload_buildstats_output(
        self, gn_results, gcs_bucket, build_id, fint_build_artifacts
    ):
        """Runs the buildstats command for Fuchsia and uploads the output files to GCS."""
        buildstats_binary_path = gn_results.tool("buildstats")
        self.m.path.mock_add_paths(buildstats_binary_path)
        if not self.m.path.exists(buildstats_binary_path):  # pragma: no cover
            # We might be trying to run buildstats after catching a build
            # failure, in which case ninja may not even have gotten as far as
            # building the buildstats tool.
            raise Exception("The build did not produce the buildstats tool")

        output_name = "fuchsia-buildstats.json"
        output_path = self.m.path.mkdtemp("buildstats").join(output_name)
        command = [
            buildstats_binary_path,
            "--ninjalog",
            fint_build_artifacts.ninja_log_path,
            "--compdb",
            fint_build_artifacts.ninja_compdb_path,
            "--graph",
            fint_build_artifacts.ninja_graph_path,
            "--output",
            output_path,
        ]
        with self.m.context(cwd=gn_results.build_dir):
            self.m.step("fuchsia buildstats", command)

        self.m.upload.file_to_gcs(
            source=output_path,
            bucket=gcs_bucket,
            subpath=output_name,
            namespace=build_id,
        )

    def _download_toolchain(self, name, toolchain, cipd_package):
        """Downloads a prebuilt toolchain from CAS or CIPD.

        Args:
            name (str): Name of the toolchain (e.g. "clang").
            toolchain (CustomToolchain): Information about where to
                download the toolchain from.
            cipd_package (str): The name of the CIPD package to download if
                toolchain_info["type"] is "cipd".

        Returns: A Path to the root of a temporary directory where the
        toolchain was downloaded.
        """
        with self.m.step.nest("%s_toolchain" % name), self.m.context(infra_steps=True):
            root_dir = self.m.path.mkdtemp(name)

            if toolchain.source == "cipd":
                pkgs = self.m.cipd.EnsureFile()
                pkgs.add_package(
                    "fuchsia/%s/${platform}" % cipd_package, str(toolchain.version)
                )
                self.m.cipd.ensure(root_dir, pkgs)
            elif toolchain.source == "isolated":
                self.m.archive.download(
                    step_name="download",
                    digest=str(toolchain.version),
                    output_dir=root_dir,
                )
            else:  # pragma: no cover
                raise KeyError(
                    '%s_toolchain source "%s" not recognized' % (name, toolchain.source)
                )

            return root_dir

    def _upload_build_results(
        self, build_results, gcs_bucket, is_release_version, namespace
    ):
        assert gcs_bucket
        # Upload archives.
        for archive in build_results.archives:
            metadata = None
            path = build_results.build_dir.join(archive["path"])

            # Try and sign the build archive. If the we are on a release build and the
            # signing script returns a signature, add it to the metadata and
            # upload the public key for verification.
            # TODO(fxb/51162): Remove once this is no longer used.
            if is_release_version and archive["name"] == "archive":
                signature = self._try_sign_archive(path)
                if signature:
                    # Add the signature to the metadata.
                    metadata = {
                        "x-goog-meta-signature": signature,
                    }

                    # Upload the public key to GCS.
                    # Note that RELEASE_PUBKEY_PATH should always exist because a
                    # signature should only be generated if RELEASE_PUBKEY_PATH exists.
                    self.m.upload.file_to_gcs(
                        source=RELEASE_PUBKEY_PATH,
                        bucket=gcs_bucket,
                        subpath=RELEASE_PUBKEY_FILENAME,
                        namespace=namespace,
                    )

            # Upload the archive
            self.m.upload.file_to_gcs(
                source=path,
                bucket=gcs_bucket,
                subpath=self.m.path.basename(path),
                namespace=namespace,
                metadata=metadata,
            )

        self._upload_binary_sizes(build_results)
        self._upload_blobstats_output(build_results, gcs_bucket, namespace)

    def _try_sign_archive(self, archive_path):
        args = [
            "--archive-file",
            archive_path,
        ]
        return self.m.python(
            "run signing script",
            self.resource("sign.py"),
            args,
            venv=self.resource("sign.py.vpython"),
            stdout=self.m.raw_io.output(),
        ).stdout

    def _upload_package_snapshot(self, build_results, gcs_bucket, build_id):
        assert gcs_bucket
        snapshot_path = build_results.build_dir.join(
            "obj", "build", "images", "system.snapshot"
        )
        if not self.m.path.exists(snapshot_path):
            return

        # Upload a new table row for the system snapshot data generated during this build
        snapshot = self.m.file.read_raw("read package snapshot file", snapshot_path)
        build_packages_entry = {
            "build_id": self.m.buildbucket.build.id,
            "snapshot": snapshot,
        }

        basename = "system.snapshot.json"
        build_packages_entry_file = self.m.path["tmp_base"].join(basename)

        self.m.step(
            "write build_packages_entry_file",
            ["cat", self.m.json.input(build_packages_entry)],
            stdout=self.m.raw_io.output(leak_to=build_packages_entry_file),
        )

        self.m.upload.file_to_gcs(
            source=build_packages_entry_file,
            bucket=gcs_bucket,
            subpath=basename,
            namespace=build_id,
        )

        # Upload a new table row describing this particular build. Other tables' rows
        # are linked into this table using the build id as a foreign key.
        builds_entry = {
            "bucket": self.m.buildbucket.bucket_v1,
            "builder": self.m.buildbucket.builder_name,
            "build_id": self.m.buildbucket.build.id,
            "gitiles_commit": [self.m.buildbucket.gitiles_commit.id],
            "datetime": str(self.m.buildbucket.build.create_time.ToDatetime()),
            "start_time": str(self.m.buildbucket.build.start_time.ToDatetime()),
            "repo": self.m.buildbucket.build_input.gitiles_commit.project,
            "arch": build_results.set_metadata.target_arch,
            "product": build_results.set_metadata.product,
            "board": build_results.set_metadata.board,
            "channel": [""],
        }

        self.m.bqupload.insert(
            step_name="add table row: %s/%s/builds_beta"
            % (BIGQUERY_PROJECT, BIGQUERY_ARTIFACTS_DATASET),
            project=BIGQUERY_PROJECT,
            dataset=BIGQUERY_ARTIFACTS_DATASET,
            table="builds_beta",
            rows=[builds_entry],
        )

    def _upload_binary_sizes(self, build_results):
        """Uploads size checks to BigQuery.

        The upload also includes metadata about this build so that the
        data can be used to create a self-contained BigQuery table.
        """
        if not build_results._binary_sizes[0]:  # pragma: no cover
            return
        metadata = {
            "builder_name": self.m.buildbucket.builder_name,
            # This field is set to a string in the BQ table schema because it's just
            # an opaque ID. The conversion from int to string that happens on the
            # BigQuery side is not what we want, so convert here.
            "build_id": str(self.m.buildbucket.build.id),
            "build_create_time_seconds": self.m.buildbucket.build.create_time.seconds,
            "gitiles_commit_host": self.m.buildbucket.gitiles_commit.host,
            "gitiles_commit_id": self.m.buildbucket.gitiles_commit.id,
            "gitiles_commit_project": self.m.buildbucket.gitiles_commit.project,
        }
        rows = []
        for component, item in build_results._binary_sizes[0].items():
            # The size_checker output includes additional meta-data for
            # binary sizes beyond just the size/budget values themselves. Some
            # of this (e.g component owner URL) is encoded as strings, which
            # do not fit with the BQ table schema for binary_sizes (and which
            # we don't really want to persist anyway). Given that we are bound
            # to the existing JSON structure (for compatibility with
            # binary-sizes gerrit plugin) filter the non-conforming items out.
            if isinstance(item, (int, float)):
                row = metadata.copy()
                row["component"] = component
                row["size"] = item
                rows.append(row)

        self.m.bqupload.insert(
            step_name="upload size_checker output",
            project=BIGQUERY_PROJECT,
            dataset=BIGQUERY_ARTIFACTS_DATASET,
            table="binary_sizes",
            rows=rows,
        )

    def _upload_blobstats_output(self, build_results, gcs_bucket, build_id):
        """Runs the blobstats command and uploads the output files to GCS."""
        dir_name = "blobstats"
        blobstats_output_dir = self.m.path["cleanup"].join(dir_name)
        with self.m.context(cwd=build_results.build_dir):
            result = self.m.step(
                "blobstats",
                [build_results.tool("blobstats"), "--output=%s" % blobstats_output_dir],
                ok_ret="any",
            )
        # If blobstats failed, it's probably because the build intentionally
        # didn't produce the input files that blobstats requires. Blobstats is
        # generally just a nice-to-have anyway, so either way it's probably okay
        # to silently continue without uploading results if blobstats fails.
        if result.retcode != 0:
            return

        self.m.upload.directory_to_gcs(
            source=blobstats_output_dir,
            bucket=gcs_bucket,
            subpath=dir_name,
            namespace=build_id,
            rsync=False,
        )

    def _upload_tracing_data(self, build_results, gcs_bucket, build_id):
        """Uploads GN and ninja tracing results for this build to GCS."""
        paths_to_upload = []
        if build_results.gn_results.gn_trace_path:
            paths_to_upload += [
                ("fuchsia_gn_trace.json", build_results.gn_results.gn_trace_path),
            ]
        with self.m.step.nest("extract ninja traces"):
            paths_to_upload += [
                (
                    "fuchsia_ninja_trace.json",
                    self._extract_ninja_tracing_data(
                        build_results, "fuchsia_ninja_trace.json"
                    ),
                ),
            ]

        with self.m.step.nest("upload traces") as presentation:
            for filename, path in paths_to_upload:
                step = self.m.upload.file_to_gcs(
                    source=path,
                    bucket=gcs_bucket,
                    subpath=filename,
                    namespace=build_id,
                )
                # Perfetto needs an unauthenticated URL.
                # TODO(fxbug.dev/66249): Perfetto cannot load non-public traces.
                # Consider hiding this link in such cases.
                step.presentation.links[
                    "perfetto_ui"
                ] = "https://ui.perfetto.dev/#!?url=%s" % (
                    self.m.gsutil.unauthenticated_url(step.presentation.links[filename])
                )
                # This is shown as a workaround to hint users on how to load
                # non-public traces.
                presentation.links[
                    "fuchsia.dev guide"
                ] = "https://fuchsia.dev/fuchsia-src/development/tracing/tutorial/converting-visualizing-a-trace#html-trace"

    def _extract_ninja_tracing_data(self, build_results, trace_name):
        """Extracts the tracing data by combining .ninjalog, compdb and graph.

        Args:
            build_results (_FuchsiaBuildResults): The results of the build.
            build_dir (Path): The build output directory.
            trace_name (str): The name of the trace file.
        """
        trace = self.m.path.mkdtemp("ninja-trace").join(trace_name)
        self.m.step(
            "ninjatrace %s" % trace_name,
            [
                build_results.tool("ninjatrace"),
                "-ninjalog",
                build_results.fint_build_artifacts.ninja_log_path,
                "-compdb",
                build_results.fint_build_artifacts.ninja_compdb_path,
                "-graph",
                build_results.fint_build_artifacts.ninja_graph_path,
                "-critical-path",
                "-trace-json",
                trace,
            ],
            stdout=self.m.raw_io.output(leak_to=trace),
        )
        return trace
