# 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.

from __future__ import annotations

import configparser
import dataclasses
import functools
import io
import re
from typing import TYPE_CHECKING

from recipe_engine import recipe_api

if TYPE_CHECKING:  # pragma: no cover
    from typing import Callable, Generator
    from recipe_engine import config_types
    from RECIPE_MODULES.fuchsia.git_roll_util import api as git_roll_util_api
    from RECIPE_MODULES.pigweed.checkout import api as checkout_api


@dataclasses.dataclass
class Submodule:
    path: str
    name: str
    branch: str
    remote: str = dataclasses.field(default=None)
    dir: config_types.Path = dataclasses.field(default=None)


@dataclasses.dataclass
class RevisionChange:
    old: str
    new: str
    finalize: Callable[[], None]


class SubmoduleRollApi(recipe_api.RecipeApi):

    Submodule = Submodule
    RevisionChange = RevisionChange

    def update_pin(
        self,
        checkout: checkout_api.CheckoutContext,
        path: config_types.Path,
        new_revision: str,
        submodule_timeout_sec: int,
    ) -> RevisionChange:
        with self.m.context(cwd=checkout.top):
            self.m.git.submodule_update(
                paths=(path,),
                timeout=submodule_timeout_sec,
            )

        old_revision = self.m.checkout.get_revision(
            path, 'get old revision', test_data='1' * 40
        )

        def finalize() -> None:
            with self.m.context(cwd=path):
                self.m.git('git fetch', 'fetch', 'origin', new_revision)
                self.m.git('git checkout', 'checkout', 'FETCH_HEAD')

        return RevisionChange(
            old=old_revision,
            new=new_revision,
            finalize=finalize,
        )

    @functools.cache
    def read_gitmodules(self, path):
        # Confirm the given path is actually a submodule.
        gitmodules = self.m.file.read_text('read .gitmodules', path)
        # Example .gitmodules file:
        # [submodule "third_party/pigweed"]
        #   path = third_party/pigweed
        #   url = https://pigweed.googlesource.com/pigweed/pigweed

        # configparser doesn't like leading whitespace on lines, despite what
        # its documentation says.
        gitmodules = re.sub(r'\n\s+', '\n', gitmodules)
        parser = configparser.RawConfigParser()
        parser.readfp(io.StringIO(gitmodules))
        return parser

    def update(
        self,
        checkout: checkout_api.CheckoutContext,
        submodule_entry: SubmoduleEntry,
    ) -> git_roll_util_api.Roll:
        submodule = Submodule(
            path=submodule_entry.path,
            name=submodule_entry.name or submodule_entry.path,
            branch=submodule_entry.branch,
        )
        submodule.dir = checkout.root / submodule.path

        with self.m.step.nest(submodule.name) as pres:
            gitmodules = self.read_gitmodules(checkout.root / '.gitmodules')

            section = f'submodule "{submodule.name}"'
            if not gitmodules.has_section(section):
                sections = gitmodules.sections()
                submodules = sorted(
                    re.sub(r'^.*"(.*)"$', r'\1', x) for x in sections
                )
                raise self.m.step.StepFailure(
                    'no submodule "{}" (submodules: {})'.format(
                        submodule.name,
                        ', '.join('"{}"'.format(x) for x in submodules),
                    )
                )

            if not submodule.branch:
                try:
                    submodule.branch = gitmodules.get(section, 'branch')
                except configparser.NoOptionError:
                    submodule.branch = 'main'

            submodule.remote = self.m.git_roll_util.normalize_remote(
                gitmodules.get(section, 'url'),
                checkout.options.remote,
            )

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

            change = self.update_pin(
                checkout,
                submodule.dir,
                new_revision,
                submodule_entry.timeout_sec or 10 * 60,
            )

            try:
                roll = self.m.git_roll_util.get_roll(
                    repo_url=submodule.remote,
                    repo_short_name=submodule.path,
                    old_rev=change.old,
                    new_rev=change.new,
                )

            except self.m.git_roll_util.BackwardsRollError:
                return []

            change.finalize()

            return [roll]
