# Copyright 2019 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.
"""Test API for checkout."""

import collections
import urllib

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.recipe_modules.pigweed.checkout import options as checkout_options
from recipe_engine import post_process, recipe_test_api

REPO = 'https://pigweed.googlesource.com/pigweed/pigweed'
MANIFEST_REPO = 'https://pigweed.googlesource.com/pigweed/manifest'

DEFAULT_MANIFEST = """
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote
    name="default_remote"
    fetch="sso://default"
    />

  <remote
    name="pigweed_remote"
    revision="main"
    fetch=".."
    review="https://pigweed.googlesource.com"
    />

  <remote
    name="pigweed-internal_remote"
    revision="main"
    fetch="https://pigweed-internal.googlesource.com"
    review="https://pigweed-internal.googlesource.com"
    />

  <remote
    name="prefixed"
    fetch="https://foo.googlesource.com/prefix"
    review="https://foo.googlesource.com/prefix"
    />

  <default
    remote="default_remote"
    revision="main"
    />

  <project
    name="default_name"
    path="default_path"
    />

  <project
    name="pigweed_name"
    path="pigweed_path"
    remote="pigweed_remote"
    revision="main"
    />

  <project
    name="pigweed-internal_name"
    path="pigweed-internal_path"
    remote="pigweed-internal_remote"
    />

  <project
    name="pinned"
    path="pinned"
    remote="pigweed_remote"
    revision="0123456789012345678901234567890123456789"
    upstream="main"
    />

  <project
    name="suffix"
    path="prefix/suffix"
    remote="prefixed"
    />
</manifest>
""".strip()


def _project(
    project: str | None = None,
    remote: str | None = None,
    default: str | None = None,
):
    if project is not None:
        return project
    if remote is None:
        assert default
        return default

    assert remote
    project = urllib.parse.urlparse(remote).path.lstrip('/')
    if project.endswith('.git'):
        project = name[0 : -len('.git')]  # pragma: no cover
    return project


def _name(name, project):
    if name is not None:
        return name

    name = project
    if name.endswith('.git'):
        name = name[0 : -len('.git')]  # pragma: no cover
    parts = name.split('/')
    if parts[-1] == 'manifest':
        parts.pop()
    return parts[-1]


class CheckoutTestApi(recipe_test_api.RecipeTestApi):
    """Test API for checkout."""

    @property
    def pigweed_repo(self):
        return REPO

    @property
    def pigweed_repo_dot_git(self):
        return f'{REPO}.git'

    @property
    def manifest_repo(self):
        return MANIFEST_REPO

    def git_options(
        self,
        *,
        remote=REPO,
        branch='main',
        use_trigger=True,
        use_repo=False,
        equivalent_remotes=(),
        force_no_rebase=False,
        match_branch=True,
        manifest_file='',
        root_subdirectory='',
        initialize_submodules=True,
        included_submodules=(),
        excluded_submodules=(),
        manifest_groups=(),
        rewrites=(),
    ):
        props = checkout_options.Options()
        props.remote = remote
        props.branch = branch or 'main'
        props.use_trigger = use_trigger
        props.use_repo = use_repo
        for remotes in equivalent_remotes:
            remote_group = checkout_options.EquivalentRemotes()
            remote_group.remotes.extend(remotes)
            props.equivalent_remotes.extend([remote_group])
        props.force_no_rebase = force_no_rebase
        props.match_branch = match_branch
        props.manifest_file = manifest_file
        props.root_subdirectory = root_subdirectory
        props.initialize_submodules = initialize_submodules
        props.included_submodules.extend(included_submodules)
        props.excluded_submodules.extend(excluded_submodules)
        props.manifest_groups.extend(manifest_groups)
        props.rewrites.extend(
            checkout_options.Rewrite(original=x, final=y) for x, y in rewrites
        )
        return props

    def repo_options(
        self,
        remote=MANIFEST_REPO,
        use_repo=True,
        manifest_file='default.xml',
        **kwargs,
    ):
        return self.git_options(
            remote=remote,
            use_repo=use_repo,
            manifest_file=manifest_file,
            **kwargs,
        )

    def ci_test_data(
        self,
        git_repo: str = REPO,
        name: str | None = None,
        branch: str | None = None,
        **kwargs,
    ):
        project = _project(remote=git_repo)
        if branch:
            kwargs['git_ref'] = f'refs/heads/{branch}'
        ret = self.m.buildbucket.ci_build(git_repo=git_repo, **kwargs)
        if branch:
            name = _name(name, project)

            ret += self.override_step_data(
                f'checkout {name}.change data.process gitiles commit.number',
                self.m.json.output(
                    [
                        {
                            '_number': '1234',
                            'branch': branch,
                            'project': project or name,
                        }
                    ]
                ),
            )
        return ret

    def cl(self, host, project, change, patchset=1):
        return common_pb2.GerritChange(
            host=host, project=project, change=change, patchset=patchset
        )

    def try_test_data(self, git_repo=REPO, **kwargs):
        return self.m.buildbucket.try_build(git_repo=git_repo, **kwargs)

    def manifest_test_data(self, name='pigweed', raw_xml=DEFAULT_MANIFEST):
        return self.step_data(
            f'checkout {name}.read manifest.read file',
            self.m.file.read_text(raw_xml),
        )

    def cl_branch_parents(
        self,
        branch='main',
        num_parents=1,
        index=0,
        name=None,
        message='',
        project=None,
        remote=None,
    ):
        project = _project(project, remote, 'pigweed/pigweed')
        name = _name(name, project)

        return self.override_step_data(
            f'checkout {name}.change data.process gerrit changes.{index}.details',
            self.m.json.output(
                {
                    'branch': branch,
                    'current_revision': 'f' * 40,
                    'revisions': {
                        'f'
                        * 40: {
                            '_number': 4,
                            'commit': {
                                'parents': [None for _ in range(num_parents)],
                                'message': message,
                            },
                        },
                    },
                    'project': project or name,
                }
            ),
        )

    def manifest_has_matching_branch(self, branch, name='pigweed'):
        # The contents of the returned JSON data don't matter--they just need to
        # evaluate to True when converted to bool. Gitiles returns an empty
        # dictionary when the branch does not exist.
        return self.m.git.get_remote_branch_head(
            f'checkout {name}.manifest has branch.git ls-remote {branch}',
            'a' * 40,
        )

    def root_files(self, *files, name='pigweed'):
        files = set(files)
        files.add('.repo')
        return self.step_data(
            f'checkout {name}.ls',
            stdout=self.m.raw_io.output_text(
                ''.join((f'{x}\n' for x in sorted(files)))
            ),
        )

    def submodule(
        self,
        path,
        remote,
        status='',
        *,
        hash='a' * 40,
        initialized=True,
        branch='main',
        name=None,
        describe='',
        modified=False,
        conflict=False,
        url=None,
        update=None,
        ignore=None,
        shallow=False,
        fetchRecurseSubmodules=None,
    ):
        result = {}
        result['path'] = path
        result['remote'] = remote
        result['hash'] = hash
        result['initialized'] = initialized
        result['branch'] = branch
        result['name'] = name or path
        result['describe'] = describe
        result['modified'] = modified
        result['conflict'] = conflict
        result['url'] = url or remote
        result['update'] = update
        result['ignore'] = ignore
        result['shallow'] = shallow
        result['fetchRecurseSubmodules'] = fetchRecurseSubmodules

        if status == '-':
            result['initialized'] = True
            result['modified'] = False
            result['conflict'] = False
        elif status == '+':
            result['initialized'] = True
            result['modified'] = True
            result['conflict'] = False
        elif status == 'U':  # pragma: no cover
            # Including for completeness but this is not expected to be used.
            result['initialized'] = True
            result['modified'] = True
            result['conflict'] = True
        elif status == ' ':
            result['initialized'] = False
            result['modified'] = False
            result['conflict'] = False

        return result

    def submodules(
        self,
        *submodules,
        prefix='checkout pigweed.',
        checkout_root='[START_DIR]/checkout',
    ):
        sub_data = {sub['path']: sub for sub in submodules}

        res = self.step_data(
            f'{prefix}submodule status',
            self.m.json.output(sub_data),
        )

        return res

    def all_changes_applied(self):
        return self.some_changes_applied() + self.post_process(
            post_process.DoesNotRunRE, '.*some changes were not applied.*'
        )

    def some_changes_applied(self):
        return self.post_process(
            post_process.DoesNotRunRE, '.*no changes were applied.*'
        )

    def no_changes_applied(self):
        return self.post_process(
            post_process.MustRunRE, '.*no changes were applied.*'
        )

    def change_applied(self, name):
        return self.post_process(
            post_process.DoesNotRunRE, f'.*failed to apply {name}.*'
        ) + self.post_process(
            post_process.MustRunRE, r'.*apply {}.git.*'.format(name)
        )

    def change_not_applied(self, name):
        return self.post_process(
            post_process.MustRunRE, f'.*failed to apply {name}.*'
        ) + self.post_process(
            post_process.DoesNotRunRE, r'.*apply {}.git.*'.format(name)
        )

    def included_submodule(self, name):
        return self.post_process(
            post_process.MustRunRE, r'.*including submodule {}'.format(name)
        ) + self.post_process(
            post_process.DoesNotRunRE, r'.*excluding submodule {}'.format(name)
        )

    def excluded_submodule(self, name):
        return self.post_process(
            post_process.DoesNotRunRE, r'.*including submodule {}'.format(name)
        ) + self.post_process(
            post_process.MustRunRE, r'.*excluding submodule {}'.format(name)
        )
