# 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 base64

from google.protobuf import text_format as textpb

from recipe_engine import recipe_api

from PB.go.chromium.org.luci.buildbucket.proto import project_config as bb_pb2
from PB.go.chromium.org.luci.cv.api.config.v2 import config as cv_config_pb2
from PB.go.chromium.org.luci.milo.api.config import project as milo_pb2


class LuciConfigApi(recipe_api.RecipeApi):
    """Module for polling and parsing luci config files via the luci-config API."""

    def fetch_config(self, config_name, message_type, project=None, local_dir=None):
        """Fetch a config file from the luci-config API and return it as a proto object.

        Args:
            config_name (str): The name of the config file to fetch, e.g.
                "commit-queue.cfg".
            message_type (type): The Python type corresponding to the
                config's protobuf message type.
            project (str): The name of the LUCI project to fetch the config
                from; e.g. "fuchsia". Defaults to the project that the
                current Buildbucket build is running in.
            local_dir (Path): If specified, assumed to point to a local
                directory of files generated by lucicfg. The specified config
                file will be read from the corresponding local file rather
                than fetching it from the LUCI Config service.
        """
        if not project:
            project = self.m.buildbucket.build.builder.project
            assert project, "buildbucket input has no project set"

        if local_dir:
            text = self.m.file.read_text(
                "read %s %s" % (project, config_name), local_dir.join(config_name)
            )
        else:
            with self.m.step.nest("fetch %s %s" % (project, config_name)):
                text = self._fetch_config_textproto(project, config_name)

        cfg = message_type()
        textpb.Parse(text, cfg)
        return cfg

    def _fetch_config_textproto(self, project, config_name):
        url = (
            "https://luci-config.appspot.com/_ah/api/config/v1/config_sets/projects/%s/config/%s"
            % (project, config_name)
        )
        token = self.m.service_account.default().get_access_token()
        response = self.m.url.get_json(
            url,
            step_name="get",
            headers={"Authorization": "Bearer %s" % token},
            default_test_data={"content": ""},
        )
        return base64.b64decode(response.output["content"])

    def buildbucket(self, **kwargs):
        return self.fetch_config("cr-buildbucket.cfg", bb_pb2.BuildbucketCfg, **kwargs)

    def commit_queue(self, config_name=None, **kwargs):
        # Support loading a CQ config file with a non-default name to support
        # projects that don't want a dedicated CQ instance but for which we
        # still want to know which tryjobs exist.
        config_name = config_name or "commit-queue.cfg"
        return self.fetch_config(config_name, cv_config_pb2.Config, **kwargs)

    def milo(self, **kwargs):
        return self.fetch_config("luci-milo.cfg", milo_pb2.Project, **kwargs)

    def get_milo_console(self, console_name, **kwargs):
        milo_cfg = self.milo(**kwargs)
        for console in milo_cfg.consoles:
            if console.id == console_name:
                return console
        return None
