# 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."""

import collections
import contextlib
import dataclasses
import re
from typing import Generator, List

from PB.recipe_engine import result as result_pb2
from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.recipe_modules.pigweed.repo_roll.tests.full import InputProperties
from PB.recipe_modules.pigweed.repo_roll.project import Project
from recipe_engine import post_process, recipe_test_api

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

PROPERTIES = InputProperties


def RunSteps(api, props):
    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) -> Generator[recipe_test_api.TestData, None, None]:
    """Create tests."""

    def properties(path):
        props = InputProperties()
        props.projects.append(Project(path_to_update=path))
        return api.properties(props)

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

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

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

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

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

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

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

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

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

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

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

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

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