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

from recipe_engine import recipe_api


class BinarySizeApi(recipe_api.RecipeApi):
    """APIs for checking and diffing binary sizes."""

    # This exit code indicates that the CI build was not successful and thus the
    # the size diff could not be computed.
    # Keep in sync with
    # https://fuchsia.googlesource.com/infra/infra/+/main/cmd/size_diff/ci.go.
    CI_BUILD_NOT_SUCCESSFUL_EXIT_CODE = 2

    def check_budgets(self, step_name, binary_sizes_json_input):
        """Check if the input binary sizes object exceeds one or more budgets.

        Args:
            step_name (str): Name of the step.
            binary_sizes_json_input (Path): Path for input binary sizes object
              as JSON.

        Raises:
            StepFailure: one or more budgets were exceeded.
        """
        args = [
            "budgets",
            "-binary-sizes-json-input",
            binary_sizes_json_input,
        ]
        step = self._run_size_check(
            step_name, args, stderr=self.m.raw_io.output_text(), ok_ret="any"
        )

        # test_ids should use underscore instead of spaces
        prepared_step = self.m.reported_step.prepare_step(
            test_id=step_name.replace(" ", "_"), step=step
        )
        try:
            if step.retcode:
                step.presentation.status = self.m.step.FAILURE
                step.presentation.logs["stderr"] = step.stderr
                prepared_step.add_artifact("stderr", step.stderr)
                raise self.m.step.StepFailure(
                    "Binary size checks failed: %s\n\nFor next steps, please refer:"
                    "http://go/tq-resilience-home/size-stats/size-check-failure-steps\n"
                    "Contact http://go/fuchsia-size-rotation if help is needed to "
                    "adjust the size budgets." % step.stderr,
                )
        finally:
            prepared_step.upload()

    def diff_ci(
        self,
        step_name,
        gitiles_remote,
        base_commit,
        ci_builder,
        binary_sizes_json_input,
    ):
        """Compute diff of the input binary sizes object against a binary sizes
        object from CI.

        Args:
            step_name (str): Name of the step.
            gitiles_remote (str): Gitiles remote for base commit.
            base_commit (str): Base commit as sha1.
            ci_builder (builder_pb2.BuilderID): CI builder to inspect.
            binary_sizes_json_input (Path): Path for input binary sizes object
              as JSON.

        Returns:
            StepData: Step data of the size diff tool.
            dict: Binary size diff with keys:
              component_diffs (seq(dict)): Per-component diffs, each with keys:
                name (str): Name of the component.
                baseline_size (int): Baseline size of the component in bytes.
                size (int): Size of the component in bytes.
                size_diff (int): Size diff in bytes.
                budget (int): Budget of the component in bytes.
                creep_budget (int): Creep budget of the component in bytes.
                budget_exceeded (bool): Whether the budget is exceeded.
                creep_budget_exceeded (bool): Whether the creep budget is
                  exceeded.
              budget_exceeded (bool): Whether one or more budgets are exceeded.
              creep_budget_exceeded (bool): Whether one or more creep budgets
                are exceeded.
              baseline_build_id (int): The baseline build ID that was used.
        """
        args = [
            "ci",
            "-gitiles-remote",
            gitiles_remote,
            "-base-commit",
            base_commit,
            "-builder",
            self.m.buildbucket_util.full_builder_name(ci_builder),
            "-binary-sizes-json-input",
            binary_sizes_json_input,
            "-json-output",
            self.m.json.output(),
        ]
        step = self._run_size_diff(
            step_name, args, ok_ret=(0, self.CI_BUILD_NOT_SUCCESSFUL_EXIT_CODE)
        )
        # If the size diff could not be computed, keep track of this as a
        # property, but do not raise an error. Computing the size diff is
        # best-effort as of now.
        step.presentation.properties["size_ci_build_not_successful"] = step.retcode == 2
        if step.retcode:
            return (step, None)
        diff = step.json.output
        step.presentation.properties["size_creep_budget_exceeded"] = diff[
            "creep_budget_exceeded"
        ]
        step.presentation.links["ci_build"] = self.m.buildbucket.build_url(
            build_id=diff["baseline_build_id"]
        )
        return (step, diff)

    @property
    def _size_check_tool(self):
        return self.m.ensure_tool(
            "size_check", self.resource("size_check/tool_manifest.json")
        )

    def _run_size_check(self, step_name, args, **kwargs):
        return self.m.step(step_name, [self._size_check_tool] + args, **kwargs)

    @property
    def _size_diff_tool(self):
        return self.m.ensure_tool(
            "size_diff", self.resource("size_diff/tool_manifest.json")
        )

    def _run_size_diff(self, step_name, args, **kwargs):
        return self.m.step(step_name, [self._size_diff_tool] + args, **kwargs)
