# 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.
"""Test of git behavior in bazel_roll module's retrieve_attributes() 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/path',
    'recipe_engine/properties',
    'recipe_engine/step',
]

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)

    entries = api.bazel_roll.retrieve_attributes(
        project_value=props.project_remote,
        path=api.path.start_dir / (props.workspace_path or 'WORKSPACE'),
        matches=checkout.remotes_equivalent,
        title_keys=('name', 'module_name'),
        search_key='remote',
    )

    api.step.empty('debug').presentation.step_summary_text = repr(entries)

    for entry in entries:
        name = entry.pop('name', '_unnamed_')
        with api.step.nest(name):
            for key, value in entry.items():
                pres = api.step.empty(key).presentation
                pres.step_summary_text = value


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.bazel_roll.workspace_file(
            '',
            api.bazel_roll.git_entry(
                comments=0,
                name='other-repo',
                remote='https://pigweed.googlesource.com/other/repo.git',
                revision="invalid commit line won't be found",
            ),
            api.bazel_roll.git_entry(
                comments=4,
                git_repository_attribute_test='ignored',
                name='pigweed',
                remote='https://pigweed.googlesource.com/pigweed/pigweed.git',
                revision='1' * 40,
                strip_prefix='pw_toolchain_bazel',
            ),
            api.bazel_roll.git_entry(
                comments=0,
                name='third-repo',
                revision='2' * 40,
                remote='https://pigweed.googlesource.com/third/repo.git',
            ),
        ),
        api.post_check(post_process.MustRun, 'pigweed'),
        api.post_check(post_process.MustRun, 'pigweed.remote'),
        api.post_check(post_process.MustRun, 'pigweed.commit'),
        api.post_check(
            post_process.MustRun,
            'pigweed.git_repository_attribute_test',
        ),
    )
