# 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

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()


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=REPO, name='pigweed', branch=None, project=None, **kwargs
    ):
        if branch:
            kwargs['git_ref'] = f'refs/heads/{branch}'
        ret = self.m.buildbucket.ci_build(git_repo=git_repo, **kwargs)
        if branch:
            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='pigweed',
        message='',
        project=None,
    ):
        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: {
                            '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)
        )
