# Copyright 2022 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.
"""Roll a pin of a git repository in a simple text file."""

from __future__ import annotations

import re
from typing import TYPE_CHECKING

import attrs
from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.recipes.pigweed.txt_roller import InputProperties
from PB.recipe_modules.pigweed.checkout.options import (
    Options as CheckoutOptions,
)
from PB.recipe_modules.pigweed.txt_roll.txt_entry import TxtEntry
from recipe_engine import post_process

if TYPE_CHECKING:  # pragma: no cover
    from typing import Generator
    from recipe_engine import recipe_api, recipe_test_api
    from RECIPE_MODULES.pigweed.checkout import api as checkout_api

DEPS = [
    'fuchsia/auto_roller',
    'pigweed/checkout',
    'pigweed/roll_util',
    'pigweed/txt_roll',
    'recipe_engine/properties',
]

PROPERTIES = InputProperties


def RunSteps(  # pylint: disable=invalid-name
    api: recipe_api.RecipeScriptApi,
    props: InputProperties,
):
    # The checkout module will try to use trigger data to pull in a specific
    # patch. Since the triggering commit is in a different repository that
    # needs to be disabled.
    props.checkout_options.use_trigger = False
    checkout: api.checkout.CheckoutContext = api.checkout(
        props.checkout_options
    )

    assert len(props.txt_entries) <= 1
    txt_entry: TxtEntry
    if props.txt_entries:
        txt_entry = props.txt_entries[0]
    else:
        txt_entry = TxtEntry(
            path=props.txt_path,
            remote=props.project_remote,
            branch=props.project_branch,
        )

    rolls = api.txt_roll.update(checkout=checkout, txt_entry=txt_entry)
    if not rolls:
        return  # pragma: no cover

    authors: Sequence[api.roll_util.Account] = api.roll_util.authors(*rolls)

    author_override: Optional[api.roll_util.Account] = None
    if len(authors) == 1 and props.forge_author:
        author_override = attrs.asdict(
            api.roll_util.fake_author(next(iter(authors)))
        )

    change: api.auto_roller.GerritChange = api.auto_roller.attempt_roll(
        props.auto_roller_options,
        repo_dir=checkout.root,
        commit_message=api.roll_util.message(*rolls),
        author_override=author_override,
    )

    return api.auto_roller.raw_result(change)


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

    def _url(x):
        assert ':' not in x
        return 'https://foo.googlesource.com/' + x

    def trigger(url, **kwargs):
        return api.checkout.ci_test_data(git_repo=_url(url), **kwargs)

    def properties(*txt_entries, **kwargs):
        props = InputProperties(**kwargs)
        props.checkout_options.CopyFrom(api.checkout.git_options())
        props.txt_entries.extend(txt_entries)
        props.forge_author = True
        props.auto_roller_options.CopyFrom(
            api.auto_roller.Options(remote=api.checkout.pigweed_repo)
        )
        return api.properties(props)

    def commit_data(name, **kwargs):
        return api.roll_util.commit_data(
            name,
            api.roll_util.commit('a' * 40, 'foo\nbar\n\nChange-Id: I1111'),
            **kwargs,
        )

    yield api.test(
        'success',
        properties(api.txt_roll.entry(path='foo.txt', remote=_url("foo"))),
        api.roll_util.properties(commit_divider='--divider--'),
        trigger('foo'),
        api.roll_util.forward_roll(),
        commit_data('foo.txt', prefix=''),
        api.auto_roller.success(),
    )

    yield api.test(
        'deprecated',
        properties(txt_path='foo.txt', project_remote=_url("foo")),
        api.roll_util.properties(commit_divider='--divider--'),
        trigger('foo'),
        api.roll_util.forward_roll(),
        commit_data('foo.txt', prefix=''),
        api.auto_roller.success(),
    )
