# 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 = [
    'pigweed/checkout',
    'pigweed/repo_roll',
    'pigweed/roll_util',
    '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('project_name').presentation
                    dir.step_summary_text = roll.project_name

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

                    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

                    direction = api.step.empty('direction').presentation
                    direction.step_summary_text = str(roll.direction)


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)

    def commit_data(name=None):
        return api.roll_util.commit_data(
            name, api.roll_util.commit('a' * 40, 'foo\nbar')
        )

    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.roll_util.forward_roll(),
        commit_data('a1'),
    )

    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.roll_util.forward_roll(),
        commit_data('b2'),
    )

    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(),
        commit_data('c3'),
    )

    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.roll_util.forward_roll(),
        commit_data('a1'),
    )

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

    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.roll_util.backward_roll(),
    )

    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(),
        commit_data('f6'),
    )

    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(),
        commit_data('g7'),
    )

    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(),
        commit_data('h8'),
    )
