# Copyright 2015 The Chromium 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 contextlib import contextmanager

from recipe_engine import recipe_api


class GomaApi(recipe_api.RecipeApi):
    """GomaApi contains helper functions for using goma."""

    def __init__(self, props, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self._enable_arbitrary_toolchains = props.enable_arbitrary_toolchains
        self._goma_dir = props.goma_dir
        self._goma_log_dir = None
        self._jobs = props.jobs
        self._server = (
            props.server or "rbe-prod1.endpoints.fuchsia-infra-goma-prod.cloud.goog"
        )
        self._use_http2 = props.use_http2

        self._goma_context = None

        self._goma_started = False

        self._goma_ctl_env = {}
        self._http2_proxy_port = 8199
        self._http2_proxy_pid_file = None
        self._recommended_jobs = None
        self._jsonstatus = None

    @property
    def json_path(self):
        assert self._goma_dir
        return self.m.path.join(self._goma_dir, "jsonstatus")

    @property
    def jsonstatus(self):  # pragma: no cover
        return self._jsonstatus

    @property
    def jobs(self):
        """Returns number of jobs for parallel build using Goma.

        Uses value from property "$infra/goma:{\"jobs\": JOBS}" if
        configured (typically in cr-buildbucket.cfg), else defaults to
        `recommended_goma_jobs`.
        """
        return self._jobs or self.recommended_goma_jobs

    @property
    def recommended_goma_jobs(self):
        """Return the recommended number of jobs for parallel build using Goma.

        Prefer to use just `goma.jobs` and configure it through default builder
        properties in cr-buildbucket.cfg.

        This function caches the _recommended_jobs.
        """
        if self._recommended_jobs is None:
            # When goma is used, 10 * self.m.platform.cpu_count is basically good in
            # various situations according to our measurement. Build speed won't
            # be improved if -j is larger than that.
            #
            # For safety, we'd like to set the upper limit to 1000.
            self._recommended_jobs = min(10 * self.m.platform.cpu_count, 1000)

        return self._recommended_jobs

    @property
    def goma_ctl(self):
        return self.m.path.join(self._goma_dir, "goma_ctl.py")

    @property
    def goma_dir(self):
        if not self._goma_dir:
            self._ensure()
        return self._goma_dir

    @property
    def _stats_path(self):
        assert self._goma_dir
        return self.m.path.join(self._goma_dir, "goma_stats.json")

    def set_path(self, path):
        self._goma_dir = path

    def _ensure(self):
        if self._goma_dir:
            return

        with self.m.step.nest("ensure goma"), self.m.context(infra_steps=True):
            self._goma_dir = self.m.path["cache"].join("goma", "client")
            self.m.cipd.ensure(
                self._goma_dir,
                self.m.cipd.EnsureFile().add_package(
                    "flutter/third_party/goma/client/${platform}", "integration"
                ),
            )

    def _run_jsonstatus(self):
        with self.m.context(env=self._goma_ctl_env):
            jsonstatus_result = self.m.python3(
                "goma jsonstatus",
                [
                    self.goma_ctl,
                    "jsonstatus",
                    self.m.json.output(leak_to=self.json_path),
                ],
                step_test_data=lambda: self.m.json.test_api.output(
                    data={
                        "notice": [
                            {
                                "infra_status": {
                                    "ping_status_code": 200,
                                    "num_user_error": 0,
                                }
                            }
                        ]
                    }
                ),
            )

        self._jsonstatus = jsonstatus_result.json.output
        if self._jsonstatus is None:
            jsonstatus_result.presentation.status = self.m.step.WARNING

    def _upload_goma_stats(self):
        stats = self.m.file.read_json(
            "read goma_stats.json",
            self._stats_path,
            test_data={},
            include_log=False,
        )
        if not (self.m.buildbucket.builder_name and self.m.buildbucket.build.id):
            # Skip the upload if it does not have build input information.
            return
        stats["build_info"] = {
            "build_id": self.m.buildbucket.build.id,
            "builder": self.m.buildbucket.builder_name,
            "time_stamp": str(self.m.time.utcnow()),
            "time_stamp_int": self.m.time.ms_since_epoch(),
        }
        self.m.step.active_result.presentation.logs["json.output"] = self.m.json.dumps(
            stats, indent=4
        ).splitlines()

        self.m.bqupload.insert(
            step_name="upload goma stats to bigquery",
            project="fuchsia-infra",
            dataset="artifacts",
            table="builds_beta_goma",
            rows=[stats],
            ok_ret="all",
        )

    def start(self):
        """Start goma compiler_proxy."""
        assert not self._goma_started

        self._ensure()

        with self.m.step.nest("setup goma") as nested_result:
            # Allow user to override from the command line.
            self._goma_ctl_env["GOMA_TMP_DIR"] = self.m.context.env.get(
                "GOMA_TMP_DIR", self.m.path["cleanup"].join("goma")
            )
            self._goma_ctl_env["GOMA_USE_LOCAL"] = False
            self._goma_log_dir = self.m.path["cleanup"]
            self._goma_ctl_env["GLOG_log_dir"] = self._goma_log_dir

            self._goma_ctl_env["GOMA_CACHE_DIR"] = self.m.path["cache"].join("goma")
            self._goma_ctl_env["GOMA_DEPS_CACHE_FILE"] = "goma_deps_cache"
            self._goma_ctl_env["GOMA_LOCAL_OUTPUT_CACHE_DIR"] = self.m.path[
                "cache"
            ].join("goma", "localoutputcache")
            self._goma_ctl_env["GOMA_STORE_LOCAL_RUN_OUTPUT"] = True

            if self._use_http2:
                self._http2_proxy_pid_file = self.m.path["tmp_base"].join(
                    "goma_http2_proxy.pid"
                )
                self.m.daemonizer.start(
                    self._http2_proxy_pid_file,
                    [
                        self._goma_dir.join("http_proxy"),
                        "-server-host",
                        self._server,
                        "-port",
                        self._http2_proxy_port,
                    ],
                )
                self._goma_ctl_env["GOMA_SERVER_HOST"] = "127.0.0.1"
                self._goma_ctl_env["GOMA_SERVER_PORT"] = str(self._http2_proxy_port)
                self._goma_ctl_env["GOMA_USE_SSL"] = "false"
            else:
                self._goma_ctl_env["GOMA_SERVER_HOST"] = self._server

            if self.m.platform.is_win:
                self._enable_arbitrary_toolchains = True
            if self._enable_arbitrary_toolchains:
                self._goma_ctl_env[
                    "GOMA_ARBITRARY_TOOLCHAIN_SUPPORT"
                ] = self._enable_arbitrary_toolchains

            self._goma_ctl_env["GOMA_DUMP_STATS_FILE"] = self._stats_path
            # The next power of 2 larger than the currently known largest
            # output (153565624) from the core.x64 profile build.
            self._goma_ctl_env["GOMA_MAX_SUM_OUTPUT_SIZE_IN_MB"] = 256

            goma_ctl_env = self._goma_ctl_env.copy()

            try:
                with self.m.context(env=goma_ctl_env):
                    self.m.python3(
                        "start goma",
                        [self.goma_ctl, "restart"],
                        infra_step=True,
                    )
                self._goma_started = True
            except self.m.step.InfraFailure as e:  # pragma: no cover
                with self.m.step.defer_results():
                    self._run_jsonstatus()
                    if self._use_http2:
                        self.m.daemonizer.stop(self._http2_proxy_pid_file)

                    with self.m.context(env=self._goma_ctl_env):
                        self.m.python3(
                            "stop goma (start failure)",
                            [self.goma_ctl, "stop"],
                        )
                nested_result.presentation.status = self.m.step.EXCEPTION
                raise e

    def stop(self):
        """Stop goma compiler_proxy.

        A user MUST execute start beforehand.
        It is user's responsibility to handle failure of stopping compiler_proxy.

        Raises:
            StepFailure if it fails to stop goma.
        """
        assert self._goma_dir
        assert self._goma_started

        with self.m.step.nest("teardown goma") as nested_result:
            try:
                with self.m.step.defer_results():
                    self._run_jsonstatus()
                    if self._use_http2:
                        self.m.daemonizer.stop(self._http2_proxy_pid_file)

                    with self.m.context(env=self._goma_ctl_env):
                        self.m.python3("goma stats", [self.goma_ctl, "stat"])
                        self.m.python3("stop goma", [self.goma_ctl, "stop"])
                self._goma_started = False

                if self._goma_log_dir:
                    compiler_proxy_warning_log_path = self._goma_log_dir.join(
                        "compiler_proxy.WARNING"
                    )
                    # Not all builds use goma, so it might not exist.
                    self.m.path.mock_add_paths(compiler_proxy_warning_log_path)
                    if self.m.path.exists(compiler_proxy_warning_log_path):
                        try:
                            self.m.file.read_text(
                                "read goma_client warning log",
                                compiler_proxy_warning_log_path,
                                test_data="test log",
                            )
                        except self.m.step.StepFailure:  # pragma: no cover
                            # Ignore. Not a big deal.
                            nested_result.presentation.status = self.m.step.EXCEPTION
                # Upload stats to BigQuery
                self._upload_goma_stats()

            except self.m.step.StepFailure:
                nested_result.presentation.status = self.m.step.EXCEPTION
                raise

    @contextmanager
    def __call__(self):
        """Make context wrapping goma start/stop.

        Raises:
            StepFailure or InfraFailure if it fails to build.
        """
        self.start()
        # Some environment needs to be set for both compiler_proxy and gomacc.
        # Push those variables used by both into context so the build can use
        # them.
        gomacc_env_vars = ["GOMA_TMP_DIR", "GOMA_USE_LOCAL"]
        gomacc_env = {
            k: v for (k, v) in self._goma_ctl_env.items() if k in gomacc_env_vars
        }

        with self.m.context(env=gomacc_env):
            try:
                yield
            finally:
                if not self.m.runtime.in_global_shutdown:
                    self.stop()
