# Copyright 2024 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's update_commit_hash() method."""

from __future__ import annotations

import dataclasses
from typing import Generator, TYPE_CHECKING

from PB.recipe_modules.pigweed.bazel.tests.update_commit_hash import (
    UpdateCommitHashProperties,
)
from PB.recipe_modules.pigweed.checkout import options as checkout_pb2
from recipe_engine import post_process

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

DEPS = [
    'pigweed/bazel',
    'pigweed/checkout',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = UpdateCommitHashProperties


@dataclasses.dataclass
class _FakeCheckoutContext:
    root: config_types.Path


def RunSteps(api, props):
    options = checkout_pb2.Options(
        remote="https://pigweed.googlesource.com/super"
    )
    equiv = checkout_pb2.EquivalentRemotes()
    equiv.remotes.append("https://pigweed.googlesource.com/pigweed/pigweed")
    equiv.remotes.append("https://pigweed.googlesource.com/pigweed/equiv")
    options.equivalent_remotes.append(equiv)
    checkout = api.checkout(options)

    # For coverage.
    path: config_types.Path | None = None
    if 'bar' in props.project_remote:
        path = api.path.start_dir / 'WORKSPACE'

    update_result = api.bazel.update_commit_hash(
        checkout=checkout,
        project_remote=props.project_remote,
        new_revision='ffffffffffffffffffffffffffffffffffffffff',
        path=path,
        replace_remote=True,
    )

    if update_result:
        step = api.step.empty('update result')
        step.presentation.step_summary_text = repr(update_result)


def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
    def properties(**kwargs):
        return api.properties(UpdateCommitHashProperties(**kwargs))

    def _url(x: str = 'pigweed/pigweed'):
        assert ':' not in x
        return f'https://pigweed.googlesource.com/{x}'

    yield api.test(
        'success',
        properties(project_remote=_url('pigweed/pigweed')),
        api.post_process(post_process.MustRun, 'update result'),
    )

    yield api.test(
        'equiv',
        properties(project_remote=_url('pigweed/equiv')),
        api.post_process(post_process.MustRun, 'update result'),
    )

    yield api.test(
        'remote-not-found',
        properties(project_remote=_url('bar')),
        api.post_process(post_process.MustRunRE, r'could not find remote.*'),
        api.post_process(post_process.DropExpectation),
        api.post_process(post_process.DoesNotRun, 'update result'),
    )

    yield api.test(
        'commit-not-found',
        properties(project_remote=_url('other/repo')),
        api.post_process(post_process.MustRunRE, r'could not find commit.*'),
        api.post_process(post_process.DropExpectation),
        api.post_process(post_process.DoesNotRun, 'update result'),
    )

    yield api.test(
        'multiple',
        properties(project_remote=_url('pigweed/pigweed')),
        api.step_data(
            'read old WORKSPACE',
            api.file.read_text(api.bazel.MULTIPLE_ROLL_WORKSPACE_FILE),
        ),
    )
