# 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 rolling of Android Repo Tool projects."""

from __future__ import annotations

import contextlib
from collections.abc import Iterator

from recipe_engine import recipe_api, recipe_test_api

from PB.recipe_modules.pigweed.repo_roll.tests.full import InputProperties

DEPS = [
    'fuchsia/gitiles',
    'fuchsia/roll_commit_message',
    'pigweed/checkout',
    'pigweed/repo_roll',
    'recipe_engine/buildbucket',
    'recipe_engine/properties',
    'recipe_engine/step',
]

INLINE_PROPERTIES_PROTO = """
import "recipe_modules/pigweed/repo_roll/project.proto";

message InputProperties {
  repeated recipe_modules.pigweed.repo_roll.Project projects = 1;
}
"""

PROPERTIES = InputProperties


def RunSteps(api: recipe_api.RecipeScriptApi, props: InputProperties):
    checkout = api.checkout.fake_context()
    checkout.options.remote = 'https://host.googlesource.com/manifest'
    checkout.options.manifest_file = 'default.xml'

    for project in props.projects:
        with contextlib.ExitStack() as stack:
            if len(props.projects) != 1:  # pragma: no cover
                stack.enter(api.step.nest(project.path_to_update))
            rolls = api.repo_roll.update_project(checkout, project)
            assert len(rolls) <= 1

            if rolls:
                roll = rolls[0]
                with api.step.nest('roll'):
                    dir = api.step.empty('repo_url').presentation
                    dir.step_summary_text = roll.repo_url

                    dir = api.step.empty('repo_short_name').presentation
                    dir.step_summary_text = roll.repo_short_name

                    old = api.step.empty('old_revision').presentation
                    old.step_summary_text = roll.old_revision

                    new = api.step.empty('new_revision').presentation
                    new.step_summary_text = roll.new_revision

                    message = api.step.empty('commit message').presentation
                    message.step_summary_text = api.roll_commit_message.format(
                        *rolls,
                        send_comment=True,
                    )


def GenTests(api) -> Iterator[recipe_test_api.TestData]:
    """Create tests."""

    def properties(*projects):
        props = InputProperties()
        props.projects.extend(projects)
        return api.properties(props)

    yield api.test(
        'success',
        properties(api.repo_roll.project('a1')),
        api.buildbucket.ci_build(git_repo='https://foo.googlesource.com/a'),
        api.repo_roll.read_step_data('a1'),
        api.gitiles.log('a1.log a1', 'A'),
    )

    yield api.test(
        'name-not-found',
        properties(api.repo_roll.project('missing')),
        api.buildbucket.ci_build(git_repo='https://bar.googlesource.com/b'),
        api.repo_roll.read_step_data('missing'),
        status='FAILURE',
    )

    yield api.test(
        'equivalent',
        properties(api.repo_roll.project('b2')),
        api.repo_roll.read_step_data('b2'),
        api.gitiles.log('b2.log b2', 'A'),
    )

    yield api.test(
        'upstream-not-set',
        properties(api.repo_roll.project('c3')),
        api.buildbucket.ci_build(git_repo='https://bar.googlesource.com/c'),
        api.repo_roll.read_step_data('c3'),
        api.gitiles.log('c3.log c3', 'A'),
    )

    yield api.test(
        'upstream-not-set-revision-not-branch',
        properties(api.repo_roll.project('d4')),
        api.buildbucket.ci_build(git_repo='https://bar.googlesource.com/c'),
        api.repo_roll.read_step_data('d4'),
        status='FAILURE',
    )

    yield api.test(
        'no-trigger-with-upstream',
        properties(api.repo_roll.project('a1')),
        api.repo_roll.read_step_data('a1'),
        api.gitiles.log('a1.log a1', 'A'),
    )

    yield api.test(
        'no-trigger-with-revision-branch',
        properties(api.repo_roll.project('c3')),
        api.repo_roll.read_step_data('c3'),
        api.gitiles.log('c3.log c3', 'A'),
    )

    yield api.test(
        'no-trigger-with-revision-hash',
        properties(api.repo_roll.project('d4')),
        api.repo_roll.read_step_data('d4'),
        status='FAILURE',
    )

    yield api.test(
        'no-trigger-with-revision-tag',
        properties(api.repo_roll.project('e5')),
        api.repo_roll.read_step_data('e5'),
        status='FAILURE',
    )

    yield api.test(
        'backwards',
        properties(api.repo_roll.project('a1')),
        api.repo_roll.read_step_data('a1'),
        api.gitiles.log('a1.log a1', 'A', n=0),
    )

    yield api.test(
        'host-dot-dot',
        properties(api.repo_roll.project('f6')),
        api.buildbucket.ci_build(git_repo='https://host.googlesource.com/f'),
        api.repo_roll.read_step_data('f6'),
        api.gitiles.log('f6.log f6', 'A'),
    )

    yield api.test(
        'dotdot-prefix',
        properties(api.repo_roll.project('g7')),
        api.buildbucket.ci_build(
            git_repo='https://host.googlesource.com/prefix/g'
        ),
        api.repo_roll.read_step_data('g7'),
        api.gitiles.log('g7.log g7', 'A'),
    )

    yield api.test(
        'host-prefix',
        properties(api.repo_roll.project('h8')),
        api.buildbucket.ci_build(
            git_repo='https://host.googlesource.com/prefix/h'
        ),
        api.repo_roll.read_step_data('h8'),
        api.gitiles.log('h8.log h8', 'A'),
    )
