# Copyright 2025 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 updating MODULE.bazel.lock files."""

from __future__ import annotations

from collections.abc import Sequence
from typing import TYPE_CHECKING

from recipe_engine import recipe_api

from RECIPE_MODULES.fuchsia.git_roll_util import api as git_roll_util_api

if TYPE_CHECKING:  # pragma: no cover
    from RECIPE_MODULES.pigweed.checkout import api as checkout_api

from PB.recipe_modules.pigweed.bazel.options import Options as BazelOptions
from PB.recipe_modules.pigweed.module_bazel_lock_roll.module_bazel_lock import (
    ModuleBazelLock,
)

from RECIPE_MODULES.fuchsia.roll_commit_message import api as rcm_api


class Roll(rcm_api.BaseRoll):
    def __init__(self, name: str, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._name = name

    def short_name(self) -> str:
        return self._name

    def message_header(self, force_summary_version: bool = False) -> str:
        del force_summary_version  # Unused.
        return self.short_name()

    def message_body(
        self,
        *,
        force_summary_version: bool = False,
        escape_tags: Sequence[str] | None = None,
        filter_tags: Sequence[str] | None = None,
    ) -> str:
        del force_summary_version  # Unused.
        del escape_tags  # Unused.
        del filter_tags  # Unused.
        return f'Regenerated {self.short_name()}'

    def message_footer(self, *, send_comment: bool) -> str:  # pragma: no cover
        del send_comment  # Unused.
        return ''

    def output_property(self) -> dict[str, str]:
        return {'name': self._name}


class ModuleBazelLockRollApi(recipe_api.RecipeApi):
    """Recipe module for updating MODULE.bazel.lock files."""

    def update(
        self,
        checkout: checkout_api.CheckoutContext,
        module_bazel_lock: ModuleBazelLock,
    ) -> list[git_roll_util_api.Roll]:
        """Updates the MODULE.bazel.lock file if it exists.

        If a `MODULE.bazel.lock` file is present at the root of the checkout,
        this method runs `bazelisk mod deps --lockfile_mode=update` to
        regenerate it based on the current `MODULE.bazel` file.

        Args:
            checkout: The checkout context.
            module_bazel_lock: Lockfile update options.
        """
        directory = checkout.root
        if module_bazel_lock.subdirectory:
            directory /= module_bazel_lock.subdirectory

        name = 'MODULE.bazel.lock'
        lock = directory / name
        self.m.path.mock_add_file(lock)
        if not self.m.path.isfile(lock):
            return []  # pragma: no cover

        with self.m.step.nest(name):
            runner = self.m.bazel.new_runner(
                checkout=checkout,
                options=BazelOptions(),
            )

            with self.m.context(cwd=directory):
                bazel = module_bazel_lock.bazel_executable
                if not bazel:
                    bazel = runner.ensure_bazelisk()
                bazel_name = self.m.path.basename(bazel)

                self.m.step(
                    f'{bazel_name} mod deps --lockfile_mode=update',
                    [
                        bazel,
                        'mod',
                        'deps',
                        '--lockfile_mode=update',
                    ],
                )

                diff = self.m.git.diff(lock, exit_code=True, ok_ret=(0, 1))
                if diff.exc_result.retcode:
                    return [Roll(name)]
                return []
