# Copyright 2019 The LUCI Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""CQ related supporting structs and functions."""

load('@stdlib//internal/luci/proto.star', 'cq_pb')
load('@stdlib//internal/validate.star', 'validate')


# A struct returned by cq.refset(...).
#
# See cq.refset(...) function for all details.
#
# Fields (all private to discourage snooping):
#   __repo: original 'repo' string as is.
#   __refs: a list of regexps for refs in the repo, as is.
#   __kind: currently always 'gob'.
#   __repo_key: a tuple with the key to use to represent the repo in dicts.
#   __gob_host: name of a gob host (e.g. 'chromium').
#   __gob_proj: name of a project on this host (e.g. 'infra/luci-py').
_refset_ctor = __native__.genstruct('cq.refset')


# A struct returned by cq.retry_config(...).
_retry_config_ctor = __native__.genstruct('cq.retry_config')


def _refset(repo=None, *, refs=None):
  """Defines a repository and a subset of its refs.

  Used in `watch` field of luci.cq_group(...) to specify what refs the CQ should
  be monitoring.

  *** note
  **Note:** Gerrit ACLs must be configured such that the CQ has read access to
  these refs, otherwise users will be waiting for the CQ to act on their CLs
  forever.
  ***

  Args:
    repo: URL of a git repository to watch, starting with `https://`. Only
        repositories hosted on `*.googlesource.com` are supported currently.
        Required.
    refs: a list of regular expressions that define the set of refs to watch for
        CLs, e.g. `refs/heads/.+`. If not set, defaults to `refs/heads/master`.

  Returns:
    An opaque struct to be passed to `watch` field of luci.cq_group(...).
  """
  repo = validate.repo_url('repo', repo)

  # Deconstruct GoB URL into a (host, repo) tuple. Support only public GoB URLs.

  host, _, proj = repo[len('https://'):].partition('/')

  if not host.endswith('.googlesource.com'):
    fail('bad "repo": only *.googlesource.com repos are supported currently')
  gob = host[:-len('.googlesource.com')]
  if gob.endswith('-review'):
    gob = gob[:-len('-review')]
  if not gob:
    fail('bad "repo": not a valid repository URL')

  if proj.startswith('a/'):
    proj = proj[len('a/'):]
  if proj.endswith('.git'):
    proj = proj[:-len('.git')]
  if not proj:
    fail('bad "repo": not a valid repository URL')

  refs = validate.list('refs', refs)
  for r in refs:
    validate.string('refs', r)

  return _refset_ctor(
      __repo = repo,
      __refs = refs or ['refs/heads/master'],
      __kind = 'gob',
      __repo_key = ('gob', gob, proj),
      __gob_host = gob,
      __gob_proj = proj,
  )


def _validate_refset(attr, val, *, default=None, required=True):
  """Validates that `val` was constructed via cq.refset(...)."""
  return validate.struct(attr, val, _refset_ctor, default=default, required=required)


def _retry_config(
      *,
      single_quota=None,
      global_quota=None,
      failure_weight=None,
      transient_failure_weight=None,
      timeout_weight=None
  ):
  """Collection of parameters for deciding whether to retry a single build.

  All parameters are integers, with default value of 0. The returned struct
  can be passed as `retry_config` field to luci.cq_group(...).

  Some commonly used presents are available as `cq.RETRY_*` constants. See
  [CQ](#cq_doc) for more info.

  Args:
    single_quota: retry quota for a single tryjob.
    global_quota: retry quota for all tryjobs in a CL.
    failure_weight: the weight assigned to each tryjob failure.
    transient_failure_weight: the weight assigned to each transient (aka
        "infra") failure.
    timeout_weight: weight assigned to tryjob timeouts.

  Returns:
    cq.retry_config struct.
  """
  val_int = lambda attr, val: validate.int(attr, val, min=0, default=0, required=False)
  return _retry_config_ctor(
      single_quota = val_int('single_quota', single_quota),
      global_quota = val_int('global_quota', global_quota),
      failure_weight = val_int('failure_weight', failure_weight),
      transient_failure_weight = val_int('transient_failure_weight', transient_failure_weight),
      timeout_weight = val_int('timeout_weight', timeout_weight),
  )


def _validate_retry_config(attr, val, *, default=None, required=True):
  """Validates that `val` was constructed via cq.retry_config(...)."""
  return validate.struct(attr, val, _retry_config_ctor, default=default, required=required)


# CQ module exposes structs and enums useful when defining luci.cq_group(...)
# entities.
#
# `cq.ACTION_*` constants define possible values for
# `allow_owner_if_submittable` field of luci.cq_group(...):
#
#   * **cq.ACTION_NONE**: don't grant additional rights to CL owners beyond
#     permissions granted based on owner's roles `CQ_COMMITTER` or
#     `CQ_DRY_RUNNER` (if any).
#   * **cq.ACTION_DRY_RUN** grants the CL owner dry run permission, even if they
#     don't have `CQ_DRY_RUNNER` role.
#   * **cq.ACTION_COMMIT** grants the CL owner commit and dry run permissions,
#     even if they don't have `CQ_COMMITTER` role.
#
# `cq.RETRY_*` constants define some commonly used values for `retry_config`
# field of luci.cq_group(...):
#
#   * **cq.RETRY_NONE**: never retry any failures.
#   * **cq.RETRY_TRANSIENT_FAILURES**: retry only transient (aka "infra")
#     failures. Do at most 2 retries across all builders. Each individual
#     builder is retried at most once. This is the default.
#   * **cq.RETRY_ALL_FAILURES**: retry all failures: transient (aka "infra")
#     failures, real test breakages, and timeouts due to lack of available bots.
#     For non-timeout failures, do at most 2 retries across all builders. Each
#     individual builder is retried at most once. Timeout failures are
#     considered "twice as heavy" as non-timeout failures (e.g. one retried
#     timeout failure immediately exhausts all retry quota for the CQ attempt).
#     This is to avoid adding more requests to an already overloaded system.
#
# `cq.COMMENT_LEVEL_*` constants define possible values for `result_visibility`
# field of luci.cq_group(...):
#   * **cq.COMMENT_LEVEL_UNSET**: Equivalent to cq.COMMENT_LEVEL_FULL for now.
#   * **cq.COMMENT_LEVEL_FULL**: The CQ reports the summary markdown and a link
#     to the buildbucket build id in Milo with the builder name in the URL in a
#     Gerrit comment.
#   * **cq.COMMENT_LEVEL_RESTRICTED**: The CQ reports a generic "Build failed:
#     https://ci.chromium.org/b/1234" with no summary markdown.
cq = struct(
    refset = _refset,
    retry_config = _retry_config,

    ACTION_NONE = cq_pb.Verifiers.GerritCQAbility.UNSET,
    ACTION_DRY_RUN = cq_pb.Verifiers.GerritCQAbility.DRY_RUN,
    ACTION_COMMIT = cq_pb.Verifiers.GerritCQAbility.COMMIT,

    RETRY_NONE = _retry_config(),
    RETRY_TRANSIENT_FAILURES = _retry_config(
        single_quota = 1,
        global_quota = 2,
        failure_weight = 100,  # +inf
        transient_failure_weight = 1,
        timeout_weight = 100,  # +inf
    ),
    RETRY_ALL_FAILURES = _retry_config(
        single_quota = 1,
        global_quota = 2,
        failure_weight = 1,
        transient_failure_weight = 1,
        timeout_weight = 2,
    ),

    COMMENT_LEVEL_UNSET = cq_pb.COMMENT_LEVEL_UNSET,
    COMMENT_LEVEL_FULL = cq_pb.COMMENT_LEVEL_FULL,
    COMMENT_LEVEL_RESTRICTED = cq_pb.COMMENT_LEVEL_RESTRICTED,
)

cqimpl = struct(
    validate_refset = _validate_refset,
    validate_retry_config = _validate_retry_config,
)
