# 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

from collections.abc import Iterator

from recipe_engine import post_process, recipe_api, recipe_test_api

from PB.recipe_modules.pigweed.bazel_roll.tests.update_value import (
    UpdateValueProperties,
)
from PB.recipe_modules.pigweed.checkout import options as checkout_pb

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

INLINE_PROPERTIES_PROTO = """
message UpdateValueProperties {
  // The path of the WORKSPACE file to update. Default: WORKSPACE.
  string workspace_path = 1;

  // Repository referred to by the WORKSPACE file.
  string project_remote = 2;

  // Provide a callback to write data instead of writing it immediately.
  bool delay_write = 3;
}
"""

PROPERTIES = UpdateValueProperties


def RunSteps(api: recipe_api.RecipeScriptApi, props: UpdateValueProperties):
    options = checkout_pb.Options(
        remote='https://pigweed.googlesource.com/super'
    )
    equiv = checkout_pb.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) -> Iterator[recipe_test_api.TestData]:
    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_check(post_process.MustRun, 'update result'),
    )

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

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

    yield api.test(
        'commit-not-found',
        properties(project_remote=_url('other/repo')),
        api.post_check(post_process.MustRunRE, r'could not find commit.*'),
        api.post_check(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_check(
            post_process.MustRun,
            'update result.project name pigweed, pw_toolchain',
        ),
    )
