# 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 dependencies in Bazel WORKSPACE or MODULE.bazel files.

This module provides the `BazelRollApi` class, which facilitates the automated
rolling of dependencies declared in Bazel build files. It supports updating:
  - `git_repository` (or `git_override`) rules by changing their `commit` attribute
    to the latest hash from a specified remote and branch.
  - `cipd_repository` rules by updating their `tag` attribute to the latest
    version resolved via `cipd_roll.select_version`.

Key features include:
  - Reading and parsing Bazel files (WORKSPACE, MODULE.bazel).
  - Locating specific dependency entries based on attributes like 'remote' (for Git)
    or 'path' (for CIPD).
  - Modifying the relevant version attribute (e.g., 'commit', 'tag').
  - Adding or updating metadata comments near the modified lines to indicate
    automatic updates.
  - Regenerating `MODULE.bazel.lock`.
  - Generating `Roll` objects for standardized commit messages.
  - Flexible matching of repository URLs and delayed file writes.
"""

from __future__ import annotations

import dataclasses
import re
from collections.abc import Callable, Sequence
from typing import TYPE_CHECKING

from recipe_engine import config_types, recipe_api

from PB.recipe_modules.pigweed.bazel_roll.cipd_package import BazelCipdPackage
from PB.recipe_modules.pigweed.bazel_roll.git_repository import GitRepository

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


def nwise(iterable, n):
    # nwise('ABCDEFG', 3) → ABC BCD CDE DEF EFG
    # See also
    # https://docs.python.org/3/library/itertools.html#itertools.pairwise
    iterator = iter(iterable)
    initial_items = [None]
    for _ in range(1, n):
        initial_items.append(next(iterator, None))
    items = tuple(initial_items)
    for x in iterator:
        items = (*items[1:], x)
        yield items


def trim_nearby_lines(lines: Sequence[LineProxy]) -> list[LineProxy]:
    # If there's a blank line in the second half, remove any following lines.
    for i in range(len(lines) // 2, len(lines)):
        text = lines[i].text or ''
        if not text.strip():
            lines = lines[0:i]
            break

    # If there's a blank line in the first half, remove any preceding lines.
    for i in range(len(lines) // 2, 0, -1):
        text = lines[i].text or ''
        if not text.strip():
            lines = lines[i:]
            break

    return lines


def proximity_sort_nearby_lines(
    lines: Sequence[LineProxy],
    center: int,
) -> list[LineProxy]:
    # Shift the order to be center-out instead of ascending.
    lines = [(abs(center - x.idx), x.idx, x) for x in lines]
    return [x[-1] for x in sorted(lines)]


@dataclasses.dataclass
class UpdateResult:
    """Holds the result of an attempt to update a value in a Bazel file.

    Attributes:
        old_value: The original value that was found and potentially replaced.
        project_name: The name of the project/repository associated with the
            update, extracted from attributes like 'name' or 'module_name'.
        finalize: An optional callable. If provided (e.g., when `delay_write`
            is True), this function must be called to actually perform the file
            modification.
    """

    old_value: str
    project_name: str | None
    finalize: Callable[[], None] | None = None


GIT_HASH_PATTERN = '[0-9a-fA-F]{40}'


class LineProxy:
    """A proxy object to interact with a line within a list of strings.

    This allows modifying a line in a list indirectly, which can be useful
    when passing around references to lines that might be replaced or
    deleted from the original list.
    """

    def __init__(self, lines: list[str | None], idx: int):
        """Initializes a LineProxy.

        Args:
            lines: The list of strings (lines of a file).
            idx: The index of the line this proxy represents.
        """
        self._lines = lines
        self._idx = idx

    @property
    def idx(self) -> int:
        """The index of the line in the original list."""
        return self._idx

    @property
    def text(self) -> str | None:
        """The text content of the line. Can be set to a new string or None."""
        return self._lines[self._idx]

    @text.setter
    def text(self, value: str | None) -> None:
        """Sets the text content of the line."""
        self._lines[self._idx] = value

    def __repr__(self) -> str:
        """String representation showing index and text."""
        return f'{self.idx} {self.text}'


def proxy(lines: list[str | None]) -> list[LineProxy]:
    """Creates a list of LineProxy objects from a list of strings."""
    return [LineProxy(lines, i) for i in range(len(lines))]


class BazelRollApi(recipe_api.RecipeApi):
    """API for updating dependencies in Bazel WORKSPACE or MODULE.bazel files.

    This includes updating `git_repository` commit hashes and `cipd_repository`
    tags. It provides utilities for reading these files, finding relevant
    dependency entries, and modifying their versions.
    """

    UpdateResult = UpdateResult
    GIT_HASH_PATTERN = GIT_HASH_PATTERN

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self._read_cache: dict[config_types.Path, Sequence[str]] = {}

    def workspace_path(
        self,
        root: config_types.Path,
        value: str,
    ) -> config_types.Path:
        """Figure out the location of the WORKSPACE or MODULE.bazel file.

        If value is '', look for root / 'WORKSPACE' and root / 'MODULE.bazel'.
        If exactly one exists, return it. If not, error out.

        If root / value is a file, return it.

        If root / value is a directory, set root = root / value and apply the
        above logic. This enables applying this logic to subdirectories.

        Args:
            api: Recipe API object.
            root: Checkout root.
            value: Relative path specified in properties.

        Returns:
            Path to the WORKSPACE or MODULE.bazel file.
        """
        if value:
            value_path = root / value
            self.m.path.mock_add_file(value_path)
            if self.m.path.isfile(value_path):
                return value_path
            elif self.m.path.isdir(value_path):  # pragma: no cover
                root = value_path
            else:
                self.m.step.empty(  # pragma: no cover
                    f'{value_path} does not exist',
                    status='FAILURE',
                )

        workspace = root / 'WORKSPACE'
        module_bazel = root / 'MODULE.bazel'

        self.m.path.mock_add_file(workspace)

        if self.m.path.isfile(module_bazel) and self.m.path.isfile(workspace):
            self.m.step.empty(  # pragma: no cover
                f'{module_bazel} and {workspace} both exist',
                status='FAILURE',
            )

        if self.m.path.isfile(module_bazel):
            return module_bazel  # pragma: no cover

        if self.m.path.isfile(workspace):
            return workspace

        self.m.step.empty(  # pragma: no cover
            'no WORKSPACE or MODULE.bazel file found',
            status='FAILURE',
        )

    def update_cipd_package(
        self,
        checkout: checkout_api.CheckoutContext,
        package: BazelCipdPackage,
        platforms: Sequence[str] | None = None,
    ) -> list[git_roll_util_api.Roll]:
        """Updates a `cipd_repository` entry in a Bazel workspace file.

        This method finds a `cipd_repository` rule in the specified
        WORKSPACE or MODULE.bazel file that matches the given package spec.
        It then determines the new version tag for this CIPD package (using
        `cipd_roll.select_version`) and updates the `tag` attribute in the
        Bazel file.

        Args:
            checkout: The checkout context.
            package: A protobuf message defining the CIPD package to update,
                including its name, spec, workspace path, ref, and tag key.
            platforms: An optional list of platforms to consider for the CIPD
                package. Defaults to a standard set of Mac and Linux platforms.

        Returns:
            A list containing a `Roll` object (from `cipd_roll`) if the
            package was updated, or an empty list if no update was needed.
        """
        if not package.name:
            package.name = self.m.cipd_roll.package_name(package.spec)

        # TODO: b/234874582 - Support Windows.
        if platforms is None:
            platforms = ('mac-amd64', 'mac-arm64', 'linux-amd64')

        with self.m.step.nest(package.name):
            workspace_path = self.workspace_path(
                checkout.root,
                package.workspace_path,
            )

            attrs = self.retrieve_attributes(
                project_value=package.spec,
                path=workspace_path,
                search_key='path',
            )
            assert len(attrs) == 1, repr(attrs)

            old_version = attrs[0]['tag']

            new_version = self.m.cipd_roll.select_version(
                spec=package.spec,
                ref=package.ref,
                tag=package.tag,
                allow_mismatched_refs=package.allow_mismatched_refs,
                platforms=platforms,
                old_version=old_version,
            )
            if not new_version:
                # select_version() failing is adequately covered by the
                # cipd_roll module.
                return []  # pragma: no cover

            update_result = self.update_value(
                project_value=package.spec,
                new_value=new_version,
                path=workspace_path,
                delay_write=True,
                search_key='path',
                value_key='tag',
                value_pattern=f'{package.tag}:.+',
                matches=checkout.remotes_equivalent,
            )
            if not update_result:
                # update_value() failing is adequately covered by
                # update_git_repository().
                self.m.step.empty(  # pragma: no cover
                    'failed to update commit hash',
                    status='FAILURE',
                )

            roll = self.m.cipd_roll.Roll(
                package_name=package.name,
                package_spec=package.spec,
                old_version=old_version,
                new_version=new_version,
            )

            update_result.finalize()

            return [roll]

    def update_git_repository(
        self,
        checkout: checkout_api.CheckoutContext,
        git_repository: GitRepository,
    ) -> list[git_roll_util_api.Roll]:
        """Updates a `git_repository` or `git_override` entry in a Bazel file.

        This method finds a `git_repository` (or `git_override`) rule in the
        specified WORKSPACE or MODULE.bazel file that matches the given remote URL.
        It then resolves the latest commit hash for the repository's specified
        branch and updates the `commit` attribute in the Bazel file.

        Args:
            checkout: The checkout context.
            git_repository: A protobuf message defining the Git repository to
                update, including its remote URL, branch, workspace path, and
                name.

        Returns:
            A list containing a `Roll` object (from `git_roll_util`) if the
            repository was updated, or an empty list if no update was needed
            (e.g., already up-to-date or a backwards roll).

        Raises:
            StepFailure: If the `update_value` call fails to find or update the
                commit hash.
        """
        project_name = git_repository.name
        if not project_name:
            project_name = git_repository.remote.split('/')[-1]
            project_name = project_name.removesuffix('.git')

        with self.m.step.nest(project_name):
            workspace_path = self.workspace_path(
                checkout.root,
                git_repository.workspace_path,
            )
            git_repository.branch = git_repository.branch or 'main'

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

            update_result = self.update_value(
                project_value=git_repository.remote,
                new_value=new_revision,
                path=workspace_path,
                delay_write=True,
                search_key='remote',
                value_key='commit',
                value_pattern=GIT_HASH_PATTERN,
                matches=checkout.remotes_equivalent,
            )
            if not update_result:
                self.m.step.empty(
                    'failed to update commit hash',
                    status='FAILURE',
                )

            try:
                roll = self.m.git_roll_util.get_roll(
                    repo_url=git_repository.remote,
                    repo_short_name=project_name,
                    old_rev=update_result.old_value,
                    new_rev=new_revision,
                )

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

                return []

            update_result.finalize()

            return [roll]

    def _read(
        self,
        path: config_types.Path,
        num_nearby_lines: int,
        allow_cache: bool = True,
    ) -> list[str | None]:
        """Reads a file and pads it with empty lines for context searching.

        The file content is cached in `self._read_cache` to avoid redundant
        reads. `num_nearby_lines` empty strings are added to the beginning and
        end of the actual file lines. This padding simplifies searching for
        patterns near the start or end of the file by ensuring there's always
        enough "context" lines available for `nwise` iteration.

        Args:
            path: The path to the file to read.
            num_nearby_lines: The number of empty lines to pad at the beginning
                and end.
            allow_cache: If True, uses the cached content if available.

        Returns:
            A list of strings representing the lines of the file, padded with
            empty strings.
        """
        lines: list[str | None] = [''] * num_nearby_lines

        if allow_cache and path in self._read_cache:
            lines.extend(self._read_cache[path])
        else:
            self._read_cache[path] = (
                self.m.file.read_text(
                    f'read old {path.name}',
                    path,
                    test_data=self.m.bazel_roll.test_api.TEST_WORKSPACE_FILE,
                )
                .strip()
                .splitlines()
            )
            lines.extend(self._read_cache[path])

        lines.extend([''] * num_nearby_lines)
        return lines

    def _get_matching_groups(
        self,
        lines: Sequence[str],
        num_nearby_lines: int,
        project_value: str,
        search_key: str,
        replace: bool = False,
        matches: Callable[[str, str], bool] | None = None,
    ) -> list[tuple[LineProxy, list[LineProxy]]]:
        """Get a list of "groups" of lines from a Bazel file.

        Example for search_key "abc" and matches "def:.+". These would be
        ignored:

            foo(
                abc = "def",
                foo = "bar",
                uvw = "xyz",
            )

            foo(
                abc = "abc",
                foo = "foo",
                xyz = "xyz",
            )

        And this would match:

            foo(
                abc = "def:123",
                foo = "foo",
                xyz = "xyz",
            )

        Retrieve the matching groups.
        """
        matching_groups: list[tuple[LineProxy, list[LineProxy]]] = []

        # This is more constraining than necessary, but ensures there aren't
        # special characters that confuse the regex.
        assert search_key.isidentifier(), search_key

        for nearby_lines in nwise(proxy(lines), num_nearby_lines * 2 + 1):
            curr = nearby_lines[len(nearby_lines) // 2]
            match = re.search(
                rf'^\s*{search_key}\s*=\s*"(?P<search>[^"]+)",?\s*$',
                curr.text,
            )
            if not match:
                continue

            match_value = match.group('search')

            def equals(x, y):
                # TODO: b/376915917 - Remove no cover pragma.
                return x == y  # pragma: no cover

            if not matches:
                # TODO: b/376915917 - Remove no cover pragma.
                matches = equals  # pragma: no cover

            if matches(match_value, project_value):
                pres = self.m.step.empty(
                    f'found matching {search_key} {match_value!r}'
                ).presentation
                pres.logs['lines'] = [repr(x) for x in nearby_lines]
                matching_groups.append((curr, nearby_lines))

                if replace and match_value != project_value:
                    curr.text = curr.text.replace(match_value, project_value)

            else:
                pres = self.m.step.empty(
                    f'found other {search_key} {match_value!r}'
                ).presentation
                pres.logs['lines'] = [repr(x) for x in nearby_lines]

        return matching_groups

    def _process_nearby_lines(
        self,
        nearby_lines: Sequence[LineProxy],
    ) -> list[LineProxy]:
        """Processes a list of nearby lines for attribute extraction.

        This involves:
        1. Trimming blank lines from the periphery of the `nearby_lines` list.
        2. Sorting the remaining lines by their proximity to the original
           center line (the line that matched the `search_key`).

        This helps in prioritizing lines closer to the `search_key` match when
        looking for other attributes like `value_key` or `title_keys`.

        Args:
            nearby_lines: A sequence of `LineProxy` objects representing the
                context around a matched line.

        Returns:
            A processed list of `LineProxy` objects, trimmed and sorted.
        """
        pres = self.m.step.empty('lines').presentation
        center = nearby_lines[len(nearby_lines) // 2].idx
        pres.logs['0_center'] = [str(center)]

        pres.logs['1_orig'] = [repr(x) for x in nearby_lines]

        nearby_lines = trim_nearby_lines(nearby_lines)
        pres.logs['2_trimmed'] = [repr(x) for x in nearby_lines]

        nearby_lines = proximity_sort_nearby_lines(nearby_lines, center)
        pres.logs['3_sorted'] = [repr(x) for x in nearby_lines]

        return nearby_lines

    def retrieve_attributes(
        self,
        project_value: str,
        path: config_types.Path,
        search_key: str,
        num_nearby_lines: int = 10,
        title_keys: Sequence[str] = ('name', 'module_name'),
        matches: Callable[[str, str], bool] | None = None,
    ) -> list[dict[str, str]]:
        """Retrieves attributes from matching groups in a Bazel file.

        This function searches a Bazel file (WORKSPACE or MODULE.bazel) for
        blocks of attributes (like `git_repository` or `cipd_repository`
        rules). It identifies these blocks by a `search_key` (e.g., 'remote'
        or 'path') matching a `project_value`. For each matching block, it
        extracts all key-value attributes.

        Args:
            project_value: The value to match for the `search_key` (e.g., a
                specific remote URL or CIPD package path).
            path: The path to the Bazel file.
            search_key: The attribute key used to identify relevant blocks
                (e.g., 'remote', 'path').
            num_nearby_lines: The number of lines around a `search_key` match to
                consider as part of the attribute block.
            title_keys: A sequence of attribute keys (e.g., 'name',
                'module_name') that, if found, will also populate an 'name'
                field in the returned dictionary for that block.
            matches: An optional callable `(found_value, project_value) -> bool`
                to determine if a `search_key`'s value matches the target
                `project_value`. Defaults to exact string equality.

        Returns:
            A list of dictionaries, where each dictionary represents a matched
            attribute block. Keys are attribute names, and values are their
            corresponding string values. An additional 'name' key might be
            present if one of the `title_keys` was found.
        """
        lines = self._read(path, num_nearby_lines)

        assert isinstance(title_keys, (list, tuple)), repr(title_keys)

        matching_groups = self._get_matching_groups(
            lines=lines,
            num_nearby_lines=num_nearby_lines,
            project_value=project_value,
            search_key=search_key,
            matches=matches,
        )

        results: list[dict[str, str]] = []
        for _, nearby_lines in matching_groups:
            entry = {}
            nearby_lines = self._process_nearby_lines(nearby_lines)

            for line in nearby_lines:
                if match := re.search(
                    r'^\s*([\w_]+)\s*=\s*(\S.*),\s*$',
                    line.text,
                ):
                    entry[match.group(1)] = match.group(2).strip('"')
                    if match.group(1) in title_keys:
                        entry['name'] = match.group(2).strip('"')

            if entry:
                results.append(entry)

        return results

    def update_value(
        self,
        *,
        project_value: str,
        new_value: str,
        path: config_types.Path,
        search_key: str,
        value_key: str,
        num_nearby_lines: int = 10,
        replace: bool = False,
        delay_write: bool = False,
        title_keys: Sequence[str] = ('name', 'module_name'),
        value_pattern: str | None = None,
        matches: Callable[[str, str], bool] | None = None,
    ) -> UpdateResult | None:
        """Updates a specific attribute's value within a matching block in a Bazel file.

        This function locates a block of attributes (e.g., a `git_repository`
        rule) using `project_value` and `search_key`. Within that block, it
        finds the line corresponding to `value_key` (e.g., 'commit' or 'tag')
        and updates its value to `new_value`. It also adds/updates metadata
        comments near the modified line.

        Args:
            project_value: The value for the `search_key` to identify the block.
            new_value: The new value to set for the `value_key` attribute.
            path: The path to the Bazel file.
            search_key: The attribute key to identify the block (e.g., 'remote').
            value_key: The attribute key whose value needs to be updated (e.g., 'commit').
            num_nearby_lines: Context lines to consider around matches.
            replace: If True, and `search_key`'s value doesn't exactly match
                     `project_value` but `matches()` returns True, the
                     `search_key`'s value will be updated to `project_value`.
            delay_write: If True, the file modification is not performed
                         immediately. Instead, a `finalize` callable is returned
                         in `UpdateResult`, which must be called to write changes.
            title_keys: Keys to identify the project name for `UpdateResult`.
            value_pattern: A regex pattern to match the existing value of `value_key`.
                           Defaults to a generic pattern if None.
            matches: A callable for flexible matching of `project_value`.

        Returns:
            An `UpdateResult` object containing the old value and project name,
            and potentially a `finalize` function if `delay_write` is True.
            Returns None if the `project_value` or `value_key` is not found.
        """
        lines = self._read(path, num_nearby_lines)

        matching_groups = self._get_matching_groups(
            lines=lines,
            num_nearby_lines=num_nearby_lines,
            project_value=project_value,
            replace=replace,
            search_key=search_key,
            matches=matches,
        )

        if not matching_groups:
            self.m.step.empty(
                f'could not find {search_key} {project_value} in {path}',
            )
            return None

        project_names: list[str] = []
        if value_pattern is None:
            # TODO: b/376915917 - Remove no cover pragma.
            value_pattern = '[^"]+'  # pragma: no cover

        for matching_line, nearby_lines in matching_groups:
            nearby_lines = self._process_nearby_lines(nearby_lines)

            value_rx = re.compile(
                rf'^(?P<prefix>\s*{value_key}\s*=\s*")'
                rf'(?P<value>{value_pattern})'
                r'(?P<suffix>",?\s*)$'
            )

            for line in nearby_lines:
                if match := value_rx.search(line.text):
                    idx = line.idx
                    break
            else:
                pres = self.m.step.empty(
                    f'could not find {value_key} line adjacent to '
                    f'{matching_line.text!r} in {path}',
                ).presentation
                pres.step_summary_text = repr(nearby_lines)
                return None

            old_value = match.group('value')

            prefix = match.group('prefix')
            suffix = match.group('suffix')
            lines[idx] = f'{prefix}{new_value}{suffix}'

            # Remove all existing metadata lines in this git_repository() entry.
            idx2 = idx - 1
            while lines[idx2].strip().startswith('# ROLL: '):
                lines[idx2] = None
                idx2 -= 1

            ws_prefix = re.search(r'^\s*', prefix).group(0)
            comment_prefix = f'{ws_prefix}# ROLL: '

            comment_lines = (
                f'{comment_prefix}Warning: this entry is automatically '
                'updated by',
                f'{comment_prefix}{self.m.buildbucket.builder_url()}',
            )

            lines[idx] = '\n'.join(comment_lines + (lines[idx],))

            assert isinstance(title_keys, (list, tuple)), repr(title_keys)

            # This is more restrictive than necessary but helps keep the regex
            # simple.
            for key in title_keys:
                assert isinstance(key, str), repr(key)
                assert key.isidentifier(), repr(key)

            for line in nearby_lines:
                keys = '|'.join(title_keys)
                if match := re.search(
                    rf'^\s*(?:{keys})\s*=\s*"(?P<value>[^"]+)",?\s*$',
                    line.text or '',
                ):
                    project_names.append(match.group('value'))
                    break

        def write():
            self.m.file.write_text(
                f'write new {path.name}',
                path,
                ''.join(
                    f'{x}\n'
                    for x in lines[num_nearby_lines:-num_nearby_lines]
                    if x is not None
                ),
            )

        if delay_write:
            return UpdateResult(
                old_value=old_value,
                project_name=', '.join(project_names),
                finalize=write,
            )

        else:
            write()

            return UpdateResult(
                old_value=old_value,
                project_name=', '.join(project_names),
            )
