# Copyright 2023 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.
"""Full test of bazel module."""

from __future__ import annotations

import dataclasses
import re
from typing import TYPE_CHECKING

from PB.recipe_modules.pigweed.bazel.tests.full import InputProperties
from recipe_engine import post_process

if TYPE_CHECKING:  # pragma: no cover
    from typing import Generator
    from recipe_engine import config_types, recipe_test_api

DEPS = [
    'pigweed/bazel',
    'recipe_engine/buildbucket',
    'recipe_engine/path',
    'recipe_engine/properties',
]

PROPERTIES = InputProperties


@dataclasses.dataclass
class _FakeCheckoutContext:
    root: config_types.Path
    bazel_overrides: dict[str, config_types.Path] = dataclasses.field(
        default_factory=dict
    )


def RunSteps(api, props):  # pylint: disable=invalid-name
    overrides = {}
    for override in props.overrides:
        overrides[override] = api.path.start_dir / 'bazel_repos' / override

    # pylint: disable=missing-function-docstring
    runner = api.bazel.new_runner(
        checkout=_FakeCheckoutContext(
            root=api.path.start_dir,
            bazel_overrides=overrides,
        ),
        options=props.bazel_options,
        continue_after_build_error=props.continue_after_build_error,
    )
    runner.run()

    # Coverage only.
    runner.ensure()


def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
    def contains_override(step: str, name: str, bzlmod=False, invert=False):
        flag = '--module_override' if bzlmod else '--override_repository'
        pattern = re.compile(rf'{flag}={name}=.*')
        check = post_process.StepCommandContains
        if invert:
            check = post_process.StepCommandDoesNotContain
        return api.post_process(check, step, pattern)

    def lacks_override(step: str, name: str, bzlmod=False):
        return contains_override(
            step=step, name=name, bzlmod=bzlmod, invert=True
        )

    yield api.test(
        'fixed-bazelisk',
        api.bazel.properties(bazelisk_version='1.19.0'),
        api.post_process(post_process.MustRun, 'ensure bazelisk'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'latest-without-overrides',
        api.bazel.properties(program=['default']),
        api.post_process(post_process.MustRun, 'ensure bazelisk'),
        lacks_override('default.test //...', 'pigweed'),
        lacks_override('default.test //...', 'thirdparty'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'latest-with-overrides',
        api.bazel.properties(program=['default']),
        api.properties(overrides=['pigweed', 'thirdparty']),
        api.post_process(post_process.MustRun, 'ensure bazelisk'),
        contains_override('default.test //...', 'pigweed'),
        contains_override('default.test //...', 'thirdparty'),
        lacks_override('default.test //...', 'additional'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'upload-but-tryjob',
        api.buildbucket.try_build(),
        api.bazel.properties(),
        api.bazel.config(remote_cache=True, upload_local_results=True),
        api.post_process(post_process.MustRun, 'ensure bazelisk'),
        api.post_process(
            post_process.MustRun,
            'ignoring upload_local_results because this is a tryjob',
        ),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'continue-after-build-error',
        api.buildbucket.try_build(),
        api.bazel.properties(),
        api.properties(continue_after_build_error=True),
        api.post_process(
            post_process.StepCommandContains,
            'bazel build //...',
            ['--keep_going'],
        ),
        api.post_process(
            post_process.StepCommandContains,
            'bazel test //...',
            ['--keep_going'],
        ),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'upload-but-no-cache',
        api.buildbucket.ci_build(),
        api.bazel.properties(),
        api.bazel.config(remote_cache=False, upload_local_results=True),
        api.post_process(post_process.MustRun, 'ensure bazelisk'),
        api.post_process(
            post_process.MustRun,
            'ignoring upload_local_results since remote_cache is False',
        ),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'upload',
        api.buildbucket.ci_build(),
        api.bazel.properties(),
        api.bazel.config(remote_cache=True, upload_local_results=True),
        api.post_process(post_process.MustRun, 'ensure bazelisk'),
        api.post_process(
            post_process.DoesNotRun,
            'ignoring upload_local_results because this is a tryjob',
        ),
        api.post_process(
            post_process.DoesNotRun,
            'ignoring upload_local_results since remote_cache is False',
        ),
        api.post_process(post_process.DropExpectation),
    )
