# 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 manifest_repo(self):
        return MANIFEST_REPO

    def git_properties(self, **kwargs):
        props = checkout_options.Options()
        props.remote = kwargs.pop('remote', REPO)
        props.branch = kwargs.pop('branch', 'main') or 'main'
        props.use_trigger = kwargs.pop('use_trigger', True)
        props.use_repo = kwargs.pop('use_repo', False)
        for remotes in kwargs.pop('equivalent_remotes', ()):
            remote_group = checkout_options.EquivalentRemotes()
            remote_group.remotes.extend(remotes)
            props.equivalent_remotes.extend([remote_group])
        props.force_no_rebase = kwargs.pop('force_no_rebase', False)
        props.match_branch = kwargs.pop('match_branch', True)
        props.manifest_file = kwargs.pop('manifest_file', '')
        props.root_subdirectory = kwargs.pop('root_subdirectory', '')
        props.initialize_submodules = kwargs.pop('initialize_submodules', True)
        props.included_submodules.extend(kwargs.pop('included_submodules', ()))
        props.excluded_submodules.extend(kwargs.pop('excluded_submodules', ()))
        assert not kwargs
        return {'checkout_options': props}

    def repo_properties(self, remote=MANIFEST_REPO, use_repo=True, **kwargs):
        kwargs.setdefault('manifest_file', 'default.xml')
        return self.git_properties(remote=remote, use_repo=use_repo, **kwargs)

    def ci_test_data(
        self, git_repo=REPO, name='pigweed', branch=None, **kwargs
    ):
        if branch:
            kwargs['git_ref'] = 'refs/heads/{}'.format(branch)
        ret = self.m.buildbucket.ci_build(git_repo=git_repo, **kwargs)
        if branch:
            ret += self.override_step_data(
                'checkout {}.change data.process gitiles commit.number'.format(
                    name
                ),
                self.m.json.output([{'_number': '1234', 'branch': branch}]),
            )
        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(
            'checkout {}.read manifest.read file'.format(name),
            self.m.file.read_text(raw_xml),
        )

    def cl_branch_parents(
        self, branch='main', num_parents=1, index=0, name='pigweed',
    ):
        return self.override_step_data(
            'checkout {}.change data.process gerrit changes.{}.details'.format(
                name, index
            ),
            self.m.json.output(
                {
                    'branch': branch,
                    'current_revision': 'f' * 40,
                    'revisions': {
                        'f'
                        * 40: {
                            'commit': {
                                'parents': [None for _ in range(num_parents)],
                            },
                        },
                    },
                }
            ),
        )

    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(
            'checkout {}.manifest has branch.git ls-remote {}'.format(
                name, branch,
            ),
            'a' * 40,
        )

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

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

        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, **kwargs):
        prefix = kwargs.pop('prefix', 'checkout pigweed.')
        checkout_root = kwargs.pop('checkout_root', '[START_DIR]/checkout')
        assert not kwargs

        sub_data = {sub['path']: sub for sub in submodules}

        res = self.step_data(
            '{}submodule status'.format(prefix), 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, '.*failed to apply {}.*'.format(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, '.*failed to apply {}.*'.format(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)
        )
