# 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.
"""Trigger another build from a recipe based on input properties."""

from __future__ import annotations

import dataclasses
from collections.abc import Sequence

from recipe_engine import recipe_api

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb
from PB.recipe_modules.pigweed.trigger.options import Options

from RECIPE_MODULES.pigweed.checkout.api import CheckoutContext
from RECIPE_MODULES.recipe_engine.buildbucket.api import Inherit


@dataclasses.dataclass
class Change:
    remote: str | None
    branch: str | None
    ref: str | None


class TriggerApi(recipe_api.RecipeApi):
    """Trigger another build from a recipe based on input properties."""

    Change = Change

    def gitiles_commit(
        self,
        change: Change,
        verbose: bool = False,
        prefer_inherit: bool = True,
    ) -> common_pb.GitilesCommit | None:
        """Construct a gitiles commit from the checkout."""
        commit = self.m.buildbucket.build.input.gitiles_commit
        if commit and commit.id:
            if verbose:
                pres = self.m.step.empty('gitiles commit present').presentation
                pres.links[commit.id] = (
                    f'https://{commit.host}/{commit.project}/+/{commit.id}'
                )
            if prefer_inherit:
                return Inherit.INHERIT
            return commit

        if verbose:
            pres = self.m.step.empty('change').presentation
            pres.step_summary_text = repr(vars(change))

        if change.remote and change.branch and len(change.ref or '') == 40:
            gerrit_host = self.m.gerrit.host_from_remote_url(change.remote)
            gitiles_host = gerrit_host.replace('-review.', '.')
            gitiles_commit = common_pb.GitilesCommit(
                host=gitiles_host,
                project=self.m.gerrit.project_from_remote_url(change.remote),
                id=change.ref,
                ref=f'refs/heads/{change.branch}',
            )

            if verbose:
                pres = self.m.step.empty(
                    'generated commit reference'
                ).presentation
                pres.links[gitiles_commit.id] = (
                    f'https://{gitiles_commit.host}/{gitiles_commit.project}'
                    f'/+/{gitiles_commit.id}'
                )
            return gitiles_commit

        if verbose:  # pragma: no cover
            self.m.step.empty('returning none')
        return None  # pragma: no cover

    def __call__(
        self,
        triggers: Sequence[Options],
        checkout: CheckoutContext,
        verbose: bool = False,
    ) -> None:
        if not triggers:
            return

        calculated_gitiles_commit: common_pb.GitilesCommit | None = None

        with (
            self.m.step.nest('trigger builders'),
            self.m.defer.context() as defer,
        ):
            for trigger in triggers:
                assert trigger.builder
                combined = [trigger.project, trigger.bucket, trigger.builder]
                name = '/'.join(x for x in combined if x)

                with self.m.step.nest(name):
                    build = self.m.buildbucket.build

                    gitiles_commit: common_pb.GitilesCommit | None = None
                    if trigger.inherit_gitiles_commit:
                        if trigger.create_gitiles_commit_if_missing:
                            assert len(checkout.changes) == 1
                            calculated_gitiles_commit = self.gitiles_commit(
                                checkout.changes[0],
                                verbose=verbose,
                            )
                            gitiles_commit = calculated_gitiles_commit

                    request = self.m.buildbucket.schedule_request(
                        project=trigger.project or build.builder.project,
                        bucket=trigger.bucket or build.builder.bucket,
                        builder=trigger.builder,
                        gitiles_commit=gitiles_commit,
                        gerrit_changes=(
                            Inherit.INHERIT
                            if trigger.inherit_gerrit_changes
                            else ()
                        ),
                        can_outlive_parent=True,
                        properties={'parent_build_id': f'{build.id}'},
                    )
                    defer(self.m.buildbucket.schedule, [request])
