# Copyright 2020 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 projects in an Android Repo Tool manifest.

This module provides the `RepoRollApi` class, which allows for automated
updates (rolls) of individual projects defined within a `repo` manifest file
(typically an XML file like `default.xml`). It handles:
  - Reading and parsing the manifest file.
  - Identifying the target project based on its path.
  - Determining the current remote URL and branch/revision of the project.
  - Resolving the latest commit hash for the project from its Git repository,
    often using information from Buildbucket triggers or a specified branch.
  - Updating the project's `revision` attribute in the manifest file.
  - Handling various manifest configurations, including default remotes and
    project-specific remotes.
  - Generating `Roll` objects suitable for creating commit messages.
"""

from __future__ import annotations

import re
import urllib
import xml.etree.ElementTree

from recipe_engine import recipe_api

from PB.recipe_modules.pigweed.repo_roll.project import Project

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 _TreeBuilder(xml.etree.ElementTree.TreeBuilder):
    def comment(self, data):
        self.start(xml.etree.ElementTree.Comment, {})
        self.data(data)
        self.end(xml.etree.ElementTree.Comment)


class RepoRollApi(recipe_api.RecipeApi):
    """Provides methods to update projects within an Android Repo Tool manifest.

    This API handles reading the repo manifest (typically an XML file),
    identifying the project to update, resolving the new revision for that
    project (often based on Gitiles commit triggers or a specified branch),
    and then updating the manifest file with the new revision.
    """

    def is_branch(self, revision: str) -> bool:
        """Return True if revision appears to be a branch name.

        Determines if a given revision string is likely a branch name rather
        than a specific commit hash or tag.

        Args:
            revision: The revision string to check.

        Returns:
            True if the revision is likely a branch name, False otherwise.
        """
        if re.search(r'^[0-9a-fA-F]{40}$', revision):
            return False
        return not revision.startswith('refs/tags/')

    # ElementTree orders attributes differently in Python 2 and 3, but if given
    # attributes in a specific order it preserves that order.
    def _order_attributes(self, root: xml.etree.ElementTree.Element) -> None:
        """Sorts XML attributes for consistent output.

        Iterates through an XML tree and sorts the attributes of each element
        alphabetically. This helps in producing a canonical XML output,
        making diffs more predictable. ElementTree preserves attribute order
        if they are provided in a specific order.

        Args:
            root: The root Element of the XML tree to process.
        """
        for el in root.iter():
            if len(el.attrib) > 1:
                new_attrib = sorted(el.attrib.items())
                el.attrib.clear()
                el.attrib.update(new_attrib)

    def update_project(
        self,
        checkout: checkout_api.CheckoutContext,
        project: Project,
    ) -> list[git_roll_util_api.Roll]:
        """Updates a single project in the repo manifest to its latest revision.

        This method identifies the specified project within the manifest,
        determines its current remote and branch, and resolves the latest
        commit on that branch. It then updates the project's revision in the
        manifest file.

        Args:
            checkout: The checkout context, providing information about the
                      current repository state, including the manifest path.
            project: A protobuf message specifying the project to update,
                     typically by its 'path_to_update' attribute.

        Returns:
            A list containing a single `Roll` object if an update was made,
            or an empty list if the project is already up-to-date or if a
            backwards roll was detected.

        Raises:
            StepFailure: If the project cannot be found in the manifest,
                         if the manifest remote and triggering remote (from
                         Buildbucket) mismatch, or if 'upstream' is not set
                         and the current revision is not a branch.
        """
        with self.m.step.nest(project.path_to_update):
            new_revision = None

            # Try to get new_revision from the trigger.
            bb_remote = None
            commit = self.m.buildbucket.build.input.gitiles_commit
            if commit and commit.project:
                new_revision = commit.id
                host = commit.host
                bb_remote = f'https://{host}/{commit.project}'

            tree = _TreeBuilder()
            parser = xml.etree.ElementTree.XMLParser(target=tree)
            parser.feed(
                self.m.file.read_text('read manifest', checkout.manifest_path)
            )
            parser.close()
            root = tree.close()

            defaults = {}
            for default in root.findall('default'):
                defaults.update(default.attrib)

            remotes = {}
            for rem in root.findall('remote'):
                remotes[rem.attrib['name']] = rem.attrib

            # Search for path_to_update and check the repository it refers to
            # matches the triggering repository. This check is mostly a config
            # check and shouldn't fail in real runs unless somebody moves around
            # project paths in the manifest without updating the builder
            # definition.
            paths_found = []
            proj = None
            proj_attrib = {}

            for proj in root.findall('project'):
                # Sometimes projects don't define something in which case we
                # need to fall back on the remote specified by the project or
                # the default for the entire manifest.
                proj_attrib = {}
                proj_attrib.update(defaults)
                remote_name = proj.attrib.get(
                    'remote', defaults.get('remote', None)
                )
                assert remote_name
                proj_attrib.update(remotes[remote_name])
                proj_attrib.update(proj.attrib)
                proj_attrib['fetch'] = self.m.sso.sso_to_https(
                    proj_attrib['fetch'],
                )

                # Apparently if path is left off name is used. This is mildly
                # infuriating, but easy to work around.
                if 'path' not in proj_attrib:
                    proj_attrib['path'] = proj_attrib['name']

                paths_found.append(proj_attrib['path'])
                if proj_attrib['path'] == project.path_to_update:
                    fetch_host = proj_attrib['fetch'].strip('/')
                    if fetch_host.startswith('..'):
                        fetch_host = urllib.parse.urljoin(
                            checkout.options.remote,
                            fetch_host,
                        )

                    manifest_remote = (
                        fetch_host.rstrip('/')
                        + '/'
                        + proj_attrib['name'].strip('/')
                    )
                    if bb_remote and not checkout.remotes_equivalent(
                        manifest_remote, bb_remote
                    ):
                        raise self.m.step.StepFailure(
                            f"repo paths don't match: {manifest_remote!r} from "
                            f'manifest and {bb_remote!r} from buildbucket'
                        )
                    break

                # Reset proj_attrib to None if this entry wasn't a match, so if
                # this is the last iteration the condition a few lines down will
                # work.
                proj_attrib = {}

            if not proj_attrib:
                raise self.m.step.StepFailure(
                    'cannot find "{}" in manifest (found {})'.format(
                        project.path_to_update,
                        ', '.join('"{}"'.format(x) for x in paths_found),
                    )
                )

            if 'upstream' in proj_attrib:
                proj_branch = proj_attrib['upstream']
            elif 'revision' in proj_attrib and self.is_branch(
                proj_attrib['revision']
            ):
                proj_branch = proj_attrib['revision']
            else:
                proj_branch = 'main'

            new_revision = self.m.git_roll_util.resolve_new_revision(
                manifest_remote,
                proj_branch,
                checkout.remotes_equivalent,
            )

            # If upstream not set we may be transitioning from tracking a branch
            # to rolling. In that case set upstream to be the revision, but only
            # if the revision appears to be a branch.
            if 'upstream' not in proj_attrib:
                if self.is_branch(proj_attrib['revision']):
                    # Explicitly update both proj.attrib and proj_attrib to
                    # minimize confusion if these statements are moved around
                    # later.
                    proj.attrib['upstream'] = proj_attrib['revision']
                    proj_attrib['upstream'] = proj.attrib['upstream']
                else:
                    raise self.m.step.StepFailure(
                        'upstream not set and revision is not a branch, '
                        'aborting'
                    )

            old_revision = proj_attrib['revision']
            # Explicitly update both proj.attrib and proj_attrib to minimize
            # confusion.
            proj_attrib['revision'] = proj.attrib['revision'] = new_revision

            try:
                roll = self.m.git_roll_util.get_roll(
                    repo_url=manifest_remote,
                    repo_short_name=project.name or project.path_to_update,
                    old_rev=old_revision,
                    new_rev=new_revision,
                )

                self._order_attributes(root)

                self.m.file.write_text(
                    'write manifest',
                    checkout.manifest_path,
                    '<?xml version="1.0" encoding="UTF-8"?>\n{}\n'.format(
                        xml.etree.ElementTree.tostring(root).decode(),
                    ),
                )

                return [roll]

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

                return []
