# Copyright 2026 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.
"""Recipe module for merging into a Git repository."""

from __future__ import annotations

import dataclasses
from collections.abc import Callable

from recipe_engine import recipe_api

from PB.recipe_modules.pigweed.merge_roll.merge import MergeEntry

from RECIPE_MODULES.fuchsia.git_roll_util import api as git_roll_util_api
from RECIPE_MODULES.pigweed.checkout import api as checkout_api


@dataclasses.dataclass
class RevisionChange:
    """Represents a change in a submodule's pinned revision.

    Attributes:
        old: The old commit hash the submodule was pinned to.
        new: The new commit hash the submodule will be pinned to.
        finalize: A callable that executes the Git merge command.
    """

    new: str
    old: str
    finalize: Callable[[], None]


class MergeRollApi(recipe_api.RecipeApi):
    """API for merging branches."""

    RevisionChange = RevisionChange

    def prepare_merge(
        self,
        checkout: checkout_api.CheckoutContext,
        new_revision: str,
    ) -> RevisionChange | None:
        """Prepares and returns a RevisionChange object for a merge.

        A `finalize` function is created that, when called, will merge the
        `new_revision`.

        Args:
            checkout: The checkout context of the main repository.
            new_revision: The new commit hash to merge.

        Returns:
            A `RevisionChange` object containing the old and new revisions,
            and a `finalize` callable to apply the update, or None if there's
            nothing to merge.
        """

        with self.m.context(cwd=checkout.top):
            self.m.git.fetch(checkout.options.remote, new_revision)

            new_commits: list[str] = []
            for pair in self.m.git.cherry(
                source=new_revision,
                destination='HEAD',
            ):
                if not pair.has_equivalent:
                    new_commits.append(pair.commit)

            if not new_commits:
                return None  # pragma: no cover

            old_revision = self.m.git.rev_parse(f'{new_commits[0]}~1')

        def finalize() -> None:
            with self.m.context(cwd=checkout.top):
                try:
                    self.m.git.merge(ref=new_revision, commit=False)
                except self.m.step.StepFailure:
                    # Merge failed, so just add all changes to known files and
                    # upload. Let CQ fail the tryjob.
                    self.m.git.add(update=True)

        return RevisionChange(
            new=new_revision,
            old=old_revision,
            finalize=finalize,
        )

    def merge(
        self,
        checkout: checkout_api.CheckoutContext,
        merge_entry: MergeEntry,
    ) -> list[git_roll_util_api.Roll]:
        """Merges a branch into the checked out branch."""
        with self.m.step.nest(merge_entry.branch):
            assert merge_entry.branch

            new_revision = self.m.git_roll_util.resolve_new_revision(
                checkout.options.remote,
                merge_entry.branch,
                checkout.remotes_equivalent,
            )

            change = self.prepare_merge(
                checkout,
                new_revision,
            )

            if not change:
                return []  # pragma: no cover

            try:
                roll = self.m.git_roll_util.get_roll(
                    repo_url=checkout.options.remote,
                    repo_short_name=merge_entry.branch,
                    new_rev=change.new,
                    old_rev=change.old,
                )

                change.finalize()

                return [roll]

            except self.m.git_roll_util.BackwardsRollError:
                props = self.m.step.empty('output property').presentation
                props.properties[merge_entry.branch] = {
                    'remote': checkout.options.remote,
                    'revision': change.new,
                }

                return []
