# 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_properties(
        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=(),
    ):
        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)

        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', message='',
    ):
        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)],
                                'message': message,
                            },
                        },
                    },
                }
            ),
        )

    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, name='pigweed'):
        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='',
        *,
        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(
            '{}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)
        )
