# Copyright 2020 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 json

from recipe_engine import recipe_api

from RECIPE_MODULES.fuchsia.utils import pluralize

from PB.go.chromium.org.luci.buildbucket.proto import (
    builder_common as builder_common_pb2,
    builds_service as builds_service_pb2,
    common as common_pb2,
)

from PB.recipe_modules.fuchsia.presubmit_util.options import Options


class PresubmitUtilApi(recipe_api.RecipeApi):
    """APIs for running presubmit tests in external projects."""

    Options = Options

    def orchestrate(
        self,
        options,
        cl_subject=None,
        file_edits=None,
        package_overrides=None,
        gclient_variables=None,
    ):
        """Orchestrate a presubmit run in an external project.

        The external project must support one of:
          1. File-edit-based overrides.
          2. Overrides via gclient properties.

        Args:
          options (presubmit_util.Options): Presubmit options.
          cl_subject (str): Subject of the CL for informational purposes.
          file_edits (list): List of (file, file_contents) pairs to edit.
          package_overrides (dict(str,str)): Mapping from package to CAS
            digest to populate package_overrides.json.
          gclient_variables (dict): Variables to pass to gclient.
        """
        change_num = None
        patchset_num = None
        file_edits = file_edits or []

        if package_overrides:
            file_edits += [
                (
                    "package_overrides.json",
                    json.dumps(package_overrides, indent=2, sort_keys=True),
                ),
            ]

        if not gclient_variables:
            change_info = self._create_cl(
                "create CL",
                options,
                subject=cl_subject,
                file_edits=file_edits,
            )
            change_num = change_info["number"]
            patchset_num = change_info["revisions"][change_info["current_revision"]][
                "number"
            ]
        try:
            # If we aren't explicitly triggering tryjobs, build IDs are resolved
            # during collection.
            build_ids = None
            # If we are, build IDs are provided by the trigger output.
            if options.trigger_tryjobs:
                properties = None
                if gclient_variables:
                    properties = {
                        "gclient_variables": gclient_variables,
                    }
                build_ids = [
                    b.id
                    for b in self._trigger_tryjobs(
                        "trigger tryjobs",
                        options,
                        change_num=change_num,
                        patchset_num=patchset_num,
                        properties=properties,
                    )
                ]
            else:
                self._trigger_cq(
                    "trigger CQ+1",
                    options,
                    change_num=change_num,
                )
            if not bool(options.tryjobs):
                self._wait_for_cq(
                    "wait for CQ",
                    options,
                    change_num=change_num,
                )
            else:
                # Give tryjobs time to start after applying CQ label.
                # This is only required in the case that we used CQ to trigger
                # tryjobs, not when we have triggered the tryjobs explicitly.
                if not options.trigger_tryjobs:
                    self.m.time.sleep(options.tryjobs_wait_secs)
                self._collect_tryjobs(
                    "collect tryjobs",
                    options,
                    change_num=change_num,
                    patchset_num=patchset_num,
                    build_ids=build_ids,
                )
        finally:
            if change_num:
                self._abandon_cl("abandon CL", options, change_num=change_num)

    def _create_cl(self, step_name, options, subject, file_edits, presentation=None):
        """Create a CL.

        Args:
          step_name (str): Name of the step.
          options (presubmit_util.Options): Presubmit options.
          subject (str): Commit message subject of CL.
          file_edits (seq((str, str))): A sequence of file edits, where each
            file edit is a pair of strings: (filepath, contents).
          presentation (Step): Add links to this step, if specified. Otherwise,
            add links to the step generated by this call.

        Returns:
          gerritpb.ChangeInfo: The CL's change info.
        """
        args = [
            "-subject",
            subject,
            "-json-output",
            self.m.json.output(),
        ]
        for filepath, contents in file_edits:
            args += ["-file-edit", "%s:%s" % (filepath, contents)]
        if options.ref:
            args += ["-ref", options.ref]
        step = self._run(step_name, options, "create-cl", args, infra_step=True)
        change_info = step.json.output
        presentation = presentation or step.presentation
        presentation.links["gerrit_link"] = "https://%s/c/%s/+/%d" % (
            options.gerrit_host,
            options.gerrit_project,
            change_info["number"],
        )
        return change_info

    def _trigger_cq(
        self,
        step_name,
        options,
        change_num,
    ):
        """Trigger dryrun on a CL.

        Args:
          step_name (str): Name of the step.
          options (presubmit_util.Options): Presubmit options.
          change_num (int): Gerrit change number.
        """
        args = [
            "-change-num",
            change_num,
            "-dryrun",
        ]
        self._run(step_name, options, "trigger-cq", args)

    def _wait_for_cq(
        self,
        step_name,
        options,
        change_num,
    ):
        """Wait on a CQ attempt for completion and get its status.

        Args:
          step_name (str): Name of the step.
          options (presubmit_util.Options): Presubmit options.
          change_num (int): Gerrit change number.
        """
        args = [
            "-change-num",
            change_num,
            "-timeout",
            "%ds" % options.timeout_secs,
            "-json-output",
            self.m.json.output(),
        ]
        step = self._run(step_name, options, "wait-for-cq", args)
        passed = step.json.output
        if not passed:
            gerrit_link = "https://%s/c/%s/+/%d" % (
                options.gerrit_host,
                options.gerrit_project,
                change_num,
            )
            self.m.step.empty(
                "CQ attempt failed",
                status="FAILURE",
                step_text="CQ attempt failed. See [gerrit UI](%s)" % gerrit_link,
            )

    def _abandon_cl(self, step_name, options, change_num):
        """Abandon a CL.

        Args:
          step_name (str): Name of the step.
          options (presubmit_util.Options): Presubmit options.
          change_num (int): Gerrit change number.
        """
        args = [
            "-change-num",
            change_num,
        ]
        self._run(step_name, options, "abandon-cl", args, infra_step=True)

    def _trigger_tryjobs(
        self,
        step_name,
        options,
        change_num=None,
        patchset_num=None,
        properties=None,
    ):
        """Trigger tryjobs on a Buildbucket-based presubmit.

        Args:
            step_name (str): Name of the step.
            options (presubmit_util.Options): Presubmit options.
            change_num (int or None): Gerrit change number.
            patchset_num (int or None): Gerrit change's patchset number.
            properties (dict or None): Input properties for the tryjobs.
        """
        reqs = []
        for builder in options.tryjobs:
            project, bucket, builder_name = builder.split("/")
            req = self.m.buildbucket.schedule_request(
                builder=builder_name,
                project=project,
                bucket=bucket,
                # Emulate "Choose Tryjobs" plugin.
                gerrit_changes=[
                    common_pb2.GerritChange(
                        host=options.tryjobs_gerrit_host or options.gerrit_host,
                        project=options.gerrit_project,
                        change=change_num,
                        patchset=patchset_num,
                    ),
                ]
                if change_num
                else [],
                properties=properties,
                # Use the server-defined settings rather than inheriting the
                # parent build's settings. The parent build's settings should
                # not necessarily match the tryjobs' settings, e.g. when
                # crossing infrastructures.
                exe_cipd_version=None,
                experimental=None,
                inherit_buildsets=False,
                gitiles_commit=None,
                priority=None,
            )
            reqs.append(req)
        with self.m.step.nest(step_name):
            return self.m.buildbucket.schedule(
                reqs,
                step_name="schedule",
                # Don't propagate ResultDB data from the tryjobs. It may be
                # useful, but it can result in a huge amount of ResultDB data if
                # we're running many tryjobs. We also don't want to pollute our
                # ResultDB data with data from other projects.
                include_sub_invs=False,
            )

    def _collect_tryjobs(
        self,
        step_name,
        options,
        change_num=None,
        patchset_num=None,
        build_ids=None,
        raise_on_failure=True,
    ):
        """Collect tryjobs on a Buildbucket-based presubmit.

        Args:
          step_name (str): Name of the step.
          options (presubmit_util.Options): Presubmit options.
          change_num (int or None): Gerrit change number.
          patchset_num (int or None): Gerrit change's patchset number.
          build_ids (seq(str)): A sequence of build ids to collect. Cannot be
            be combined with options.tryjobs.
          raise_on_failure (bool): Whether to raise on tryjob failure(s).

        Raises:
          InfraFailure: One or more tryjobs completed with INFRA_FAILURE status.
          StepFailure: One or more tryjobs completed with FAILURE status.
        """
        with self.m.step.nest(step_name) as presentation:
            tryjobs = options.tryjobs if not build_ids else None
            if tryjobs:
                assert (
                    change_num and patchset_num
                ), "cannot search builders without a patchset"
                predicates = []
                for builder in tryjobs:
                    project, bucket, builder_name = builder.split("/")
                    predicate = builds_service_pb2.BuildPredicate(
                        builder=builder_common_pb2.BuilderID(
                            project=project,
                            bucket=bucket,
                            builder=builder_name,
                        ),
                        gerrit_changes=[
                            common_pb2.GerritChange(
                                host=options.tryjobs_gerrit_host or options.gerrit_host,
                                project=options.gerrit_project,
                                change=change_num,
                                patchset=patchset_num,
                            ),
                        ],
                    )
                    predicates.append(predicate)
                build_ids = [
                    b.id
                    for b in self.m.buildbucket.search(
                        step_name="search",
                        predicate=predicates,
                    )
                ]
                if len(build_ids) < len(tryjobs):
                    presentation.status = self.m.step.EXCEPTION
                    raise self.m.step.InfraFailure(
                        "expected search results to contain %d builds, got %d; "
                        "builds may have failed to have been scheduled, or the "
                        "queried builders may not exist"
                        % (len(tryjobs), len(build_ids)),
                    )
            builds = self.m.buildbucket.collect_builds(
                step_name="collect",
                build_ids=build_ids,
                timeout=options.timeout_secs,
            )
            try:
                self.m.buildbucket_util.display_builds(
                    step_name="display",
                    builds=builds.values(),
                    raise_on_failure=raise_on_failure,
                )
            except self.m.step.StepFailure:
                failed_tryjobs = [
                    b.builder.builder
                    for b in builds.values()
                    if b.status != common_pb2.SUCCESS
                ]
                gerrit_link = None
                if change_num:
                    gerrit_link = "https://%s/c/%s/+/%d" % (
                        options.gerrit_host,
                        options.gerrit_project,
                        change_num,
                    )
                raise self.m.step.StepFailure(
                    "%s failed:%s\n\n%s"
                    % (
                        pluralize("external tryjob", len(failed_tryjobs)),
                        " see [gerrit UI](%s):" % gerrit_link if gerrit_link else "",
                        "\n".join(["- %s" % t for t in failed_tryjobs]),
                    )
                )
            return builds

    def _run(self, step_name, options, subcmd_name, args, infra_step=False):
        assert options.gerrit_host
        assert options.gerrit_project
        cmd = [
            self._presubmit_util_tool,
            subcmd_name,
            "-gerrit-host",
            options.gerrit_host,
            "-gerrit-project",
            options.gerrit_project,
        ] + args
        return self.m.step(step_name, cmd, infra_step=infra_step)

    @property
    def _presubmit_util_tool(self):
        return self.m.ensure_tool("cl-util", self.resource("tool_manifest.json"))
