# Copyright 2019 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 PB.go.chromium.org.luci.cq.api.config.v2 import cq as config_pb2
from recipe_engine import recipe_api
from google.protobuf import text_format as textpb


class CommitQueueApi(recipe_api.RecipeApi):
  """Module for polling parsing commit-queue.cfg."""

  def __init__(self, *args, **kwargs):
    super(CommitQueueApi, self).__init__(*args, **kwargs)
    self._cfg = None

  def _load(self, project):
    if self._cfg:
      return

    with self.m.step.nest('get commit-queue'):
      endpoint = 'config/v1/config_sets'
      config_set = 'projects/%s/config' % project
      config = 'commit-queue.cfg'
      url = 'https://luci-config.appspot.com/_ah/api/{}/{}/{}'.format(
          endpoint, config_set, config)
      response = self.m.url.get_json(url, step_name='get')

      step = self.m.step('response', None)
      step.presentation.logs['raw'] = [repr(response.output)]
      text = base64.b64decode(response.output['content'])
      step.presentation.logs['decoded'] = [text]
      self._cfg = config_pb2.Config()
      textpb.Parse(text, self._cfg)

  def all_tryjobs(self, project='fuchsia', include_experimental=False):
    self._load(project)

    res = set()
    if self._cfg:
      for group in self._cfg.config_groups:
        for builder in group.verifiers.tryjob.builders:
          if include_experimental or not builder.experiment_percentage:
            res.add(builder.name)

    step = self.m.step('all_tryjobs', None)
    step.presentation.logs['tryjobs'] = sorted(res)
    return res
