# 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.
"""Recipe module for updating commit pins stored in plain text files.

This module provides the `TxtRollApi` for scenarios where a dependency's
commit hash is stored directly as the sole content of a text file.
This is a simpler form of version pinning compared to variable assignments
or structured manifest files.

The API handles:
  - Reading the current commit hash from the specified text file.
  - Resolving the latest commit hash from a remote Git repository and branch.
  - Comparing the current and new hashes.
  - Overwriting the text file with the new hash if it represents a forward roll.
  - Generating `Roll` objects for standardized commit messages.
"""

from __future__ import annotations

from recipe_engine import recipe_api

from PB.recipe_modules.pigweed.txt_roll.txt_entry import TxtEntry

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


class TxtRollApi(recipe_api.RecipeApi):
    """API for updating commit pins stored in plain text files.

    This module handles scenarios where a dependency's commit hash is stored
    directly in a text file (e.g., a file containing just the commit hash).
    It can update this hash to the latest commit from a specified remote
    repository and branch.
    """

    def update(
        self,
        checkout: checkout_api.CheckoutContext,
        txt_entry: TxtEntry,
    ) -> list[git_roll_util_api.Roll]:
        """Updates a commit hash in a text file to the latest from a remote.

        This function reads a text file expected to contain a commit hash.
        It resolves the latest revision from the specified remote and branch.
        If the new revision is different and represents a forward roll,
        it overwrites the text file with the new revision and generates a
        `Roll` object for commit message formatting.

        Args:
            checkout: The checkout context.
            txt_entry: A protobuf message defining the text file to update,
                       including its path, the remote URL to track, the branch,
                       and an optional name for the roll.

        Returns:
            A list containing a `Roll` object if the file was updated,
            or an empty list if no update was needed (e.g., already
            up-to-date or a backwards roll).
        """
        with self.m.step.nest(txt_entry.path):
            branch = txt_entry.branch or 'main'

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

            full_txt_path = checkout.root / txt_entry.path

            old_revision = self.m.file.read_text(
                'read old revision',
                full_txt_path,
                test_data='1' * 40,
            ).strip()

            with self.m.step.nest('txt_path') as pres:
                pres.step_summary_text = repr(txt_entry.path)

            try:
                roll = self.m.git_roll_util.get_roll(
                    repo_url=txt_entry.remote,
                    repo_short_name=txt_entry.name or txt_entry.path,
                    old_rev=old_revision,
                    new_rev=new_revision,
                )

            except self.m.git_roll_util.BackwardsRollError:
                props = self.m.step.empty('output property').presentation
                props.properties[txt_entry.path] = {
                    'remote': txt_entry.remote,
                    'revision': new_revision,
                }

                return []

            self.m.file.write_text(
                'write new revision', full_txt_path, f'{new_revision}\n'
            )

            return [roll]
