# 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, f'{step}.bazel', 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),
    )
