# 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/platform',
    '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(
        '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(
        'remote',
        api.platform.name('linux'),
        api.buildbucket.ci_build(),
        api.bazel.properties(),
        api.bazel.config(remote=True),
        api.post_process(post_process.MustRun, 'ensure bazelisk'),
        api.post_process(
            post_process.StepCommandContains,
            'bazel build //...',
            ['--config=remote'],
        ),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'remote-ignored-on-mac',
        api.platform.name('mac'),
        api.buildbucket.ci_build(),
        api.bazel.properties(),
        api.bazel.config(remote=True),
        api.post_process(post_process.MustRun, 'ensure bazelisk'),
        api.post_process(
            post_process.MustRun,
            'ignoring remote because not running on Linux',
        ),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'instance-name-open-ci',
        api.buildbucket.ci_build(project='pigweed'),
        api.bazel.properties(),
        api.bazel.config(remote_cache=True),
        api.post_process(
            post_process.StepCommandContains,
            'bazel build //...',
            [
                '--bes_instance_name=pigweed-rbe-open',
                '--remote_instance_name=projects/pigweed-rbe-open/instances/default-instance',
            ],
        ),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'instance-name-private-cq',
        api.buildbucket.try_build(),
        api.bazel.properties(),
        api.bazel.config(remote_cache=True),
        api.post_process(
            post_process.StepCommandContains,
            'bazel build //...',
            [
                '--bes_instance_name=pigweed-rbe-private-pre',
                '--remote_instance_name=projects/pigweed-rbe-private-pre/instances/default_instance',
            ],
        ),
        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 since remote_cache is False',
        ),
        api.post_process(post_process.DropExpectation),
    )
