# 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_roll module's update_value() method."""

from __future__ import annotations

import dataclasses
from typing import TYPE_CHECKING

from PB.recipe_modules.pigweed.bazel_roll.tests.update_value import (
    UpdateValueProperties,
)
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_roll',
    'pigweed/checkout',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = UpdateValueProperties


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)

    path = api.path.start_dir / 'WORKSPACE'

    update_result = api.bazel_roll.update_value(
        project_value=props.project_remote,
        new_value='f' * 40,
        path=path,
        replace=True,
        delay_write=props.delay_write,
        search_key='remote',
        value_key='commit',
        value_pattern=api.bazel_roll.GIT_HASH_PATTERN,
        matches=checkout.remotes_equivalent,
    )

    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_value}')
            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(UpdateValueProperties(**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.DoesNotRun, 'update result'),
        api.post_process(post_process.DropExpectation),
    )

    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_roll.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_roll.MULTIPLE_ROLL_WORKSPACE_FILE_2),
        ),
        api.post_process(
            post_process.MustRun,
            'update result.project name pigweed, pw_toolchain',
        ),
    )
