# 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,
        delay_write=props.delay_write,
    )

    if update_result:
        if update_result.finalize:
            update_result.finalize()

        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'),
            delay_write=True,
        ),
        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',
        ),
    )
