# 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, goma_properties, *args, **kwargs):
        super(GomaApi, self).__init__(*args, **kwargs)

        self._goma_context = None

        self._goma_started = False

        self._goma_ctl_env = {}
        self._is_local = "goma_dir" in goma_properties
        self._enable_arbritrary_toolchains = goma_properties.get(
            "enable_arbritrary_toolchains", False
        )
        self._goma_dir = goma_properties.get("goma_dir", None)
        self._goma_log_dir = None
        self._jobs = goma_properties.get("jobs", None)
        self._server = goma_properties.get("server", None)
        self._use_http2 = goma_properties.get("use_http2", False)
        self._http2_proxy_port = 8199
        self._http2_proxy_pid_file = None
        self._recommended_jobs = None
        self._jsonstatus = None

        self._deps_cache = goma_properties.get("deps_cache", True)
        self._local_output_cache = goma_properties.get("local_output_cache", True)

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

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

    @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):
        assert self._goma_dir
        return self._goma_dir

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

    def ensure(self, canary=False):
        if self._is_local:
            return self._goma_dir

        with self.m.step.nest("ensure goma") as step_result:
            if canary:
                step_result.presentation.step_text = "using canary goma client"
                step_result.presentation.status = self.m.step.WARNING

            with self.m.context(infra_steps=True):
                pkgs = self.m.cipd.EnsureFile()
                ref = "release"
                if canary:
                    ref = "candidate"
                pkgs.add_package("fuchsia/third_party/goma/client/${platform}", ref)
                self._goma_dir = self.m.path["cache"].join("goma", "client")

                self.m.cipd.ensure(self._goma_dir, pkgs)
                return self._goma_dir

    def _run_jsonstatus(self):
        with self.m.context(env=self._goma_ctl_env):
            jsonstatus_result = self.m.python(
                name="goma_jsonstatus",
                script=self.goma_ctl,
                args=["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):
        test_data = {}
        json_obj = self.m.file.read_json(
            "read goma_stats.json", self.stats_path, test_data=test_data
        )
        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
        build_dict = {
            "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(),
        }
        json_obj["build_info"] = build_dict
        self.m.file.write_json("write goma_stats.json", self.stats_path, json_obj)
        self.m.step.active_result.presentation.logs["json.output"] = self.m.json.dumps(
            json_obj, indent=4
        ).splitlines()

        self.m.bqupload.insert(
            step_name="upload goma_stats_to BQ: fuchsia-infra/artifacts/builds_beta_goma",
            project="fuchsia-infra",
            dataset="artifacts",
            table="builds_beta_goma",
            data_file=self.stats_path,
            ignore_failure=True,
        )

    def start(self, env=None, **kwargs):
        """Start goma compiler_proxy.

        A user MUST execute ensure_goma beforehand. It is user's
        responsibility to handle failure of starting compiler_proxy.
        """
        assert self._goma_dir
        assert not self._goma_started
        # TODO(olivernewman): Determine if the default value can be removed for this
        # parameter. If not, add a test to cover the case where it's not passed.
        env = env or {}

        with self.m.step.nest("pre_goma") as nested_result:
            if "GOMA_TMP_DIR" not in env:
                # 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")
                )
            if "GOMA_USE_LOCAL" not in env:
                self._goma_ctl_env["GOMA_USE_LOCAL"] = False
            if "GLOG_log_dir" not in env:
                self._goma_log_dir = self.m.path["cleanup"]
                self._goma_ctl_env["GLOG_log_dir"] = self._goma_log_dir

            # TODO(57683): Remove this once the bug is fixed in upstream.
            if "GOMA_SEND_EXPECTED_OUTPUTS" not in env:
                env["GOMA_SEND_EXPECTED_OUTPUTS"] = True
            if "GOMA_CACHE_DIR" not in env:
                self._goma_ctl_env["GOMA_CACHE_DIR"] = self.m.path["cache"].join("goma")
            if self._deps_cache:
                if "GOMA_DEPS_CACHE_FILE" not in env:
                    self._goma_ctl_env["GOMA_DEPS_CACHE_FILE"] = "goma_deps_cache"
            if self._local_output_cache:
                if "GOMA_LOCAL_OUTPUT_CACHE_DIR" not in env:
                    self._goma_ctl_env["GOMA_LOCAL_OUTPUT_CACHE_DIR"] = self.m.path[
                        "cache"
                    ].join("goma", "localoutputcache")
                if "GOMA_STORE_LOCAL_RUN_OUTPUT" not in env:
                    self._goma_ctl_env["GOMA_STORE_LOCAL_RUN_OUTPUT"] = True
            if "GOMA_SERVER_HOST" in env:  # pragma: no cover
                self._server = env["GOMA_SERVER_HOST"]

            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_arbritrary_toolchains = True
            if self._enable_arbritrary_toolchains:
                if "GOMA_ARBITRARY_TOOLCHAIN_SUPPORT" not in env:
                    self._goma_ctl_env[
                        "GOMA_ARBITRARY_TOOLCHAIN_SUPPORT"
                    ] = self._enable_arbritrary_toolchains

            self._goma_ctl_env["GOMA_DUMP_STATS_FILE"] = self.stats_path

            goma_ctl_env = self._goma_ctl_env.copy()
            goma_ctl_env.update(env)

            try:
                with self.m.context(env=goma_ctl_env):
                    self.m.python(
                        name="start_goma",
                        script=self.goma_ctl,
                        args=["restart"],
                        infra_step=True,
                        **kwargs
                    )
                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.python(
                            name="stop_goma (start failure)",
                            script=self.goma_ctl,
                            args=["stop"],
                            **kwargs
                        )
                nested_result.presentation.status = self.m.step.EXCEPTION
                raise e

    def stop(self, **kwargs):
        """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("post_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.python(
                            name="goma_stats",
                            script=self.goma_ctl,
                            args=["stat"],
                            **kwargs
                        )
                        self.m.python(
                            name="stop_goma",
                            script=self.goma_ctl,
                            args=["stop"],
                            **kwargs
                        )

                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 build_with_goma(self, env=None):
        """Make context wrapping goma start/stop.

        Raises:
            StepFailure or InfraFailure if it fails to build.
        """
        env = env or {}
        self.start(env)
        # 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:
                self.stop()
