# Copyright 2020 The Pigweed 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
#
#     https://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.
"""Recipe for testing recipes."""

from typing import Generator

from PB.recipes.pigweed.recipes import InputProperties
from recipe_engine import recipe_test_api

DEPS = [
    'fuchsia/recipe_testing',
    'pigweed/checkout',
    'recipe_engine/buildbucket',
    'recipe_engine/cv',
    'recipe_engine/defer',
    'recipe_engine/properties',
]

PROPERTIES = InputProperties

# If this build is being triggered from a change to this recipe, we need
# to explicitly pass a CL. The most recent passing run of
# pigweed.try/recipes could have any number of different subbuilds kicked
# off. In that case alter the recipes build to run on a specific CL that
# modifies the xrefs recipe alone, because that recipe is used by
# relatively few CQ builders.
SELFTEST_CL = (
    'https://pigweed-review.googlesource.com/c/infra/recipes/+/109554/1'
)

# If this build is being triggered from a change to this recipe, and we're
# using the Buildbucket testing codepath, then we need to explicitly pass a
# builder. This builder will run in the case that the only affected recipe is
# this one, so we are guaranteed to exercise the scheduling codepath without
# recursing infinitely.
SELFTEST_BUILDER = {
    'pigweed': 'pigweed/pigweed.try/pigweed-linux-gn-main',
    'pigweed-internal': 'pigweed-internal/internal.try/lucicfg',
}

COMMIT_QUEUE_CFG = """
    submit_options: <
      max_burst: 4
      burst_delay: <
        seconds: 480
      >
    >

    config_groups: <
      gerrit: <
        url: "https://pigweed-review.googlesource.com"
        projects: <
          name: "project"
          ref_regexp: "refs/heads/.+"
        >
      >

      verifiers: <
        gerrit_cq_ability: <
          committer_list: "project-pigweed-committers"
          dry_run_access_list: "project-pigweed-tryjob-access"
        >
        tryjob: <
          builders: <
            name: "pigweed/try/pigweed-baz"
            location_filters <
              gerrit_host_regexp: ".*"
              gerrit_project_regexp: ".*"
              path_regexp: ".*"
              exclude: true
            >
          >
        >
      >
    >

    config_groups: <
      gerrit: <
        url: "https://pigweed-review.googlesource.com"
        projects: <
          name: "pigweed/pigweed"
          ref_regexp: "refs/heads/.+"
        >
      >
      verifiers: <
        gerrit_cq_ability: <
          committer_list: "project-pigweed-committers"
          dry_run_access_list: "project-pigweed-tryjob-access"
        >

        tryjob: <
          builders: <
            name: "pigweed/try/pigweed-bar"
            location_filters <
              gerrit_host_regexp: ".*"
              gerrit_project_regexp: ".*"
              path_regexp: ".*"
              exclude: true
            >
          >
          builders: <
            name: "pigweed/try/pigweed-foo"
            location_filters <
              gerrit_host_regexp: ".*"
              gerrit_project_regexp: ".*"
              path_regexp: ".*"
              exclude: true
            >
          >
        >
      >
    >
"""


def RunSteps(api, props):
    if props.unittest_only:
        # A unittest-only run should never be flaky.
        api.cv.set_do_not_retry_build()

    checkout = api.checkout(props.checkout_options)

    with api.defer.context() as defer:
        defer(
            api.recipe_testing.run_lint,
            checkout.root,
            allowlist='configparser|io|urllib|xml',
        ),
        defer(api.recipe_testing.run_unit_tests, checkout.root),

    if not props.unittest_only:
        api.recipe_testing.run_tests(
            checkout.root,
            SELFTEST_CL,
            props.recipe_testing_options,
            selftest_builder=SELFTEST_BUILDER[
                api.buildbucket.build.builder.project
            ],
        )


def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
    """Create tests."""

    def properties(**kwargs):
        props = InputProperties(**kwargs)
        props.checkout_options.CopyFrom(api.checkout.git_options())
        return api.properties(props)

    yield (
        api.test('cq_try')
        + properties(unittest_only=False)
        + api.recipe_testing.options((api.recipe_testing.project('pigweed'),))
        + api.checkout.try_test_data(project='pigweed')
        + api.recipe_testing.commit_queue_config_data(
            'pigweed', COMMIT_QUEUE_CFG
        )
        + api.recipe_testing.affected_recipes_data(['none'])
        + api.recipe_testing.build_data(
            'pigweed/try/pigweed-foo', 'pigweed', skip=True
        )
        + api.recipe_testing.build_data(
            'pigweed/try/pigweed-bar', 'pigweed', skip=True
        )
        + api.recipe_testing.build_data(
            'pigweed/try/pigweed-baz', 'project', skip=True
        )
    )

    yield (
        api.test('unittest-only')
        + properties(unittest_only=True)
        + api.checkout.try_test_data()
    )
