# 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 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 typing import Generator
    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:
        with api.step.nest('update result'):
            api.step.empty(f'old revision {update_result.old_revision}')
            api.step.empty(f'project name {update_result.project_name}')


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),
        ),
    )

    yield api.test(
        'multiple-2',
        properties(project_remote=_url('pigweed/pigweed')),
        api.step_data(
            'read old WORKSPACE',
            api.file.read_text(api.bazel.MULTIPLE_ROLL_WORKSPACE_FILE_2),
        ),
        api.post_process(
            post_process.MustRun,
            'update result.project name pigweed, pw_toolchain',
        ),
    )
