# Copyright 2020 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.
"""Roll a submodule of a git repository."""

import re

import attr
from PB.recipes.pigweed.submodule_roller import InputProperties
from recipe_engine import post_process
from six.moves import configparser
from six.moves import urllib
from six import StringIO

DEPS = [
    'fuchsia/auto_roller',
    'fuchsia/git',
    'fuchsia/status_check',
    'pigweed/checkout',
    'pigweed/cq_deps',
    'pigweed/roll_util',
    'recipe_engine/buildbucket',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"


@attr.s
class _RevisionChange(object):
    old = attr.ib(type=str)
    new = attr.ib(type=str)


def _update_submodule(api, path, new_revision):
    old_revision = api.checkout.get_revision(
        path, 'get old revision', test_data='1' * 40
    )

    with api.context(cwd=path):
        api.git('git fetch', 'fetch', 'origin', new_revision)
        api.git('git checkout', 'checkout', 'FETCH_HEAD')

    # In case new_revision is a branch name we need to retrieve the hash it
    # resolved to.
    if not re.search(r'^[0-9a-f]{40}$', new_revision):
        new_revision = api.checkout.get_revision(
            path, 'get new revision', test_data='2' * 40
        )

    return _RevisionChange(old=old_revision, new=str(new_revision))


def _process_deps(api, rolls, submodules, gerrit_name):
    """Process any dependencies and add them to rolls.

    Process any dependencies ("Requires:" lines) in the one initial entry in
    rolls and add them to rolls.

    Args:
        api: Recipe api object.
        rolls (dict[str,api.roll_util.Roll]): List of rolls, initially of
            length one but added to by this function.
        submodules (list[api.checkout.Submodule]): List of submodules in this
            checkout.
        gerrit_name (str): Name of initial gerrit server.

    Returns:
        Nothing.
    """

    deps = {}

    # Initially, there should only be one entry in rolls.
    assert len(rolls) == 1
    submodule_path = list(rolls)[0]
    submodule_dir = api.checkout.root.join(submodule_path)

    for commit in rolls[submodule_path].commits:
        dependencies, unresolved = api.cq_deps.resolve(
            gerrit_name, commit.hash, statuses=('MERGED',)
        )

        if unresolved:
            with api.step.nest('failed to resolve some dependencies') as pres:
                for dep in unresolved:
                    pres.links[dep.name] = dep.gerrit_url

        for dep in dependencies:
            deps[dep.name] = dep

    # Ok, this is complicated, so I'll go over what it's supposed to do
    # with an example. Suppose we're trying to roll commit 1 of submodule A.
    # That commit depends on commit 2 of submodule B and commit 3 of
    # submodule C. Commit 3 of submodule C depends on commit 4 of submodule
    # B. Submodule B is referenced twice, with commits 2 and 4. Commit 4 is
    # on top of commit 2, so we should roll B to commit 4 and skip the
    # intermediate step of commit 2.

    # Loop over all the dependencies and apply them all. If we see commit B4
    # first, we ignore commit B2 when we see it because it's a backwards
    # roll to go from B4 to B2. If we see commit B2 first, we roll to it
    # (B2~1..B2) and then we update the roll when we see B4 (to B2~1..B4).
    # The end result is that we are only rolling to B4 but the various
    # commits that roll brings includes B2.

    # The list of revisions between old_revision and new_revision isn't
    # processed until api.roll_util.message() is called in the
    # api.auto_roller.attempt_roll() call, so having an intermediate state
    # where we have a partial version of the final roll doesn't affect
    # anything.

    # Also handle various other cases like where the dependency is not in
    # the checkout or access to the dependency is forbidden. Does not yet
    # handle the case where an unrolled parent CL has unrolled dependencies.

    with api.step.nest('deps') as pres:
        pres.step_summary_text = repr(deps)

    for dep in deps.values():
        found_dep = False

        for sub in submodules:
            if not api.checkout.remotes_equivalent(dep.remote, sub.remote):
                continue
            found_dep = True

            with api.step.nest('applying {}'.format(dep.name)) as pres:
                old_revision = sub.hash
                if sub.relative_path in rolls:
                    old_revision = rolls[sub.relative_path].old_revision
                with api.context(cwd=submodule_dir):
                    api.git(
                        'fetch {}'.format(dep.commit),
                        'fetch',
                        dep.remote,
                        dep.commit,
                    )
                direction = api.roll_util.get_roll_direction(
                    submodule_dir, old_revision, dep.commit
                )

                if api.roll_util.can_roll(direction):
                    _update_submodule(api, sub.path, dep.commit)
                    rolls[sub.relative_path] = api.roll_util.Roll(
                        project_name=sub.relative_path,
                        old_revision=old_revision,
                        new_revision=dep.commit,
                        proj_dir=sub.path,
                        direction=direction,
                    )
                    pres.step_summary_text = 'applied'

                else:
                    api.roll_util.skip_roll_step(
                        dep.remote, old_revision, dep.commit,
                    )
                    pres.step_summary_text = 'already applied'

        if not found_dep:
            with api.step.nest('skipping required {}'.format(dep.name)) as pres:
                pres.step_summary_text = 'repository is not in checkout'


def RunSteps(api, props):  # pylint: disable=invalid-name
    submodule_path = props.submodule_path
    submodule_name = props.submodule_name or submodule_path
    submodule_branch = props.submodule_branch or None
    dry_run = props.dry_run
    cc_authors_on_rolls = props.cc_authors_on_rolls
    cc_reviewers_on_rolls = props.cc_reviewers_on_rolls
    cc_domains = props.cc_domains
    always_cc = props.always_cc

    # The checkout module will try to use trigger data to pull in a specific
    # patch. Since the triggering commit is in a different repository that
    # needs to be disabled.
    api.checkout(use_trigger=False)

    new_revision = None

    # Try to get new_revision from the trigger.
    bb_remote = None
    commit = api.buildbucket.build.input.gitiles_commit
    if commit and commit.project:
        new_revision = commit.id
        host = commit.host
        bb_remote = 'https://{}/{}'.format(host, commit.project)

    # Confirm the given path is actually a submodule.
    gitmodules = api.file.read_text(
        'read .gitmodules', api.checkout.root.join('.gitmodules')
    )
    # 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(StringIO(gitmodules))
    section = 'submodule "{}"'.format(submodule_name)
    if not parser.has_section(section):
        sections = parser.sections()
        submodules = sorted(re.sub(r'^.*"(.*)"$', r'\1', x) for x in sections)
        raise api.step.StepFailure(
            'no submodule "{}" (submodules: {})'.format(
                submodule_name, ', '.join('"{}"'.format(x) for x in submodules)
            )
        )

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

    # If we still don't have a revision then there wasn't a trigger. (Perhaps
    # this was manually triggered.) In this case we update to the
    # property-specified or inferred submodule branch HEAD.
    if new_revision is None:
        new_revision = submodule_branch

    # This isn't used until much later but needs to be invoked before any
    # submodules get updated.
    submodules = api.checkout.submodules(api.checkout.root)

    submodule_dir = api.checkout.root.join(submodule_path)

    remote = api.roll_util.normalize_remote(
        parser.get(section, 'url'), api.checkout.remote,
    )

    # If this was triggered by a gitiles poller, check that the triggering
    # repository matches submodule_path.
    if bb_remote:
        if not api.checkout.remotes_equivalent(remote, bb_remote):
            raise api.step.StepFailure(
                'triggering repository ({}) does not match submodule remote '
                '({})'.format(bb_remote, remote)
            )

    change = _update_submodule(api, submodule_dir, new_revision)

    direction = api.roll_util.get_roll_direction(
        submodule_dir, change.old, change.new
    )

    # If the primary roll is not necessary or is backwards we can exit
    # immediately and don't need to check deps.
    if not api.roll_util.can_roll(direction):
        api.roll_util.skip_roll_step(remote, change.old, change.new)
        return

    rolls = {
        submodule_path: api.roll_util.Roll(
            project_name=str(submodule_path),
            old_revision=change.old,
            new_revision=change.new,
            proj_dir=submodule_dir,
            direction=direction,
        ),
    }

    gerrit_name = urllib.parse.urlparse(remote).netloc.split('.')[0]

    if len(rolls[submodule_path].commits) >= 10:
        with api.step.nest('too many commits, not processing dependencies'):
            pass

    else:
        _process_deps(api, rolls, submodules, gerrit_name)

    cc = set()
    if cc_authors_on_rolls:
        cc.update(api.roll_util.authors(*rolls.values()))
    if cc_reviewers_on_rolls:
        cc.update(api.roll_util.reviewers(*rolls.values()))

    def include_cc(email):
        return api.roll_util.include_cc(
            email, cc_domains, api.checkout.gerrit_host()
        )

    # include_cc() writes steps, so we want things sorted before calling it.
    cc = sorted(set(cc))
    cc = [x for x in cc if include_cc(x)]

    roll_kwargs = {}
    if always_cc:
        roll_kwargs['cc'] = cc
    else:
        roll_kwargs['cc_on_failure'] = cc

    change = api.auto_roller.attempt_roll(
        gerrit_host=api.checkout.gerrit_host(),
        gerrit_project=api.checkout.gerrit_project(),
        upstream_ref=api.checkout.branch,
        repo_dir=api.checkout.root,
        commit_message=api.roll_util.message(*rolls.values()),
        dry_run=dry_run,
        labels_to_set=api.roll_util.labels_to_set,
        labels_to_wait_on=api.roll_util.labels_to_wait_on,
        bot_commit=props.bot_commit,
        **roll_kwargs
    )

    return api.auto_roller.raw_result(change)


def GenTests(api):  # pylint: disable=invalid-name
    """Create tests."""

    def _url(x):
        if x.startswith(('https://', 'sso://', '.')):
            return x
        return 'https://foo.googlesource.com/' + x

    def trigger(url, **kwargs):
        return api.checkout.ci_test_data(git_repo=_url(url), **kwargs)

    def gitmodules(**submodules):
        branches = {}
        for k, v in submodules.items():
            if k.endswith('_branch'):
                branches[k.replace('_branch', '')] = v

        for x in branches:
            del submodules['{}_branch'.format(x)]

        text = []
        for k, v in sorted(submodules.items()):
            text.append(
                '[submodule "{0}"]\n\tpath = {0}\n\turl = {1}\n'.format(
                    k, _url(v)
                )
            )
            if k in branches:
                text.append('\tbranch = {}\n'.format(branches[k]))

        return api.step_data(
            'read .gitmodules', api.file.read_text(''.join(text))
        )

    def properties(**kwargs):
        new_kwargs = api.checkout.git_properties()
        new_kwargs.update(kwargs)
        new_kwargs.setdefault('dry_run', True)
        return api.properties(**new_kwargs)

    def commit_data(name, **kwargs):
        return api.roll_util.commit_data(
            name,
            api.roll_util.commit('a' * 40, 'foo\nbar\n\nChange-Id: I1111'),
            **kwargs
        )

    yield (
        api.status_check.test('success-sso-cc-authors')
        + properties(submodule_path='a1', cc_authors_on_rolls=True)
        + trigger('a1')
        + commit_data('a1', prefix='')
        + gitmodules(a1='sso://foo/a1')
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('failure-cc-authors', status='failure')
        + properties(submodule_path='a1', cc_authors_on_rolls=True)
        + trigger('a1')
        + commit_data('a1', prefix='')
        + gitmodules(a1='https://foo.googlesource.com/a1')
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_failure()
    )

    yield (
        api.status_check.test('relative-dot', status='failure')
        + properties(submodule_path='a1', cc_authors_on_rolls=True)
        + trigger('https://pigweed.googlesource.com/pigweed/pigweed/a1')
        + commit_data('a1', prefix='')
        + gitmodules(a1='./a1')
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_failure()
    )

    yield (
        api.status_check.test('relative-dotdot', status='failure')
        + properties(submodule_path='a1', cc_authors_on_rolls=True)
        + trigger('https://pigweed.googlesource.com/pigweed/a1')
        + commit_data('a1', prefix='')
        + gitmodules(a1='../a1')
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_failure()
    )

    yield (
        api.status_check.test(
            'relative-dotdot-dotdot-always-cc-reviewers', status='failure',
        )
        + properties(
            submodule_path='a1', cc_reviewers_on_rolls=True, always_cc=True,
        )
        + trigger('https://pigweed.googlesource.com/a1')
        + commit_data('a1', prefix='')
        + gitmodules(a1='../../a1')
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_failure()
    )

    yield (
        api.status_check.test('name-not-found', status='failure')
        + properties(submodule_path='a1')
        + trigger('a1')
        + gitmodules(b2='b2', c3='c3', d4='d4')
    )

    yield (
        api.status_check.test('trigger-mismatch', status='failure')
        + properties(submodule_path='a1')
        + trigger('a1')
        + gitmodules(a1='b2')
    )

    yield (
        api.status_check.test('trigger-mismatch-equivalent')
        + properties(
            submodule_path='a1',
            **api.checkout.git_properties(
                equivalent_remotes=(
                    (
                        'https://foo.googlesource.com/a1',
                        'https://foo.googlesource.com/b2',
                    ),
                ),
            )
        )
        + trigger('a1')
        + commit_data('a1', prefix='')
        + gitmodules(a1='b2')
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('with-branch-prop-filter-emails')
        + properties(
            submodule_path='a1',
            submodule_branch='branch',
            cc_authors_on_rolls=True,
            cc_reviewers_on_rolls=True,
            cc_domains=['google.com'],
        )
        + commit_data('a1', prefix='')
        + gitmodules(a1='a1', a1_branch='not_used')
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('no-revision')
        + properties(submodule_path='a1')
        + commit_data('a1', prefix='')
        + gitmodules(a1='a1', a1_branch='custom')
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('backwards')
        + properties(submodule_path='a1')
        + trigger('a1')
        + gitmodules(a1='a1')
        + api.roll_util.backward_roll()
    )

    def assert_too_many():
        return api.post_process(
            post_process.MustRun,
            'too many commits, not processing dependencies',
        )

    atoz = 'abcdefghijklmnopqrstuvwxyz'

    yield (
        api.status_check.test('too-many-skip-deps')
        + properties(submodule_path='a1', cc_authors_on_rolls=True)
        + trigger('a1')
        + api.roll_util.commit_data(
            'a1', *[api.roll_util.commit(x * 40, x) for x in atoz]
        )
        + gitmodules(a1='sso://foo/a1')
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_success()
        + assert_too_many()
    )

    # Much of the step data in the tests using "Requires:" is sufficient to
    # test the logic that processes the immediate result of the the
    # corresponding step, but does not make sense as a whole.
    def requires_test(name, *requires, **kwargs):
        assert requires
        status = kwargs.pop('status', 'success')
        assert not kwargs
        return (
            api.status_check.test(name, status=status)
            + properties(submodule_path='spam')
            + trigger('spam', revision='2' * 40)
            + gitmodules(spam='spam', ham='ham')
            + api.checkout.submodules(
                spam='https://foo.googlesource.com/spam',
                ham='https://foo.googlesource.com/ham',
                eggs='https://foo.googlesource.com/eggs',
                prefix='',
            )
            + api.cq_deps.details(
                'foo:2000', message='Requires: {}'.format(','.join(requires)),
            )
            + api.roll_util.commit_data(
                'spam', api.roll_util.commit('2' * 40), prefix='',
            )
            + api.roll_util.forward_roll()
        )

    # CL 2000 requires CL 444 in ham which has not rolled.
    yield (
        requires_test('with-requires', 'foo:444')
        + api.cq_deps.details('foo:444', status='MERGED', project='ham')
        + api.roll_util.commit_data(
            'ham', api.roll_util.commit('2' * 40), prefix='applying foo:444.',
        )
        + api.roll_util.forward_roll('applying foo:444.')
        + api.auto_roller.dry_run_success()
    )

    # CL 2000 requires CL 444 in ham which has already rolled.
    yield (
        requires_test('with-requires-already-applied', 'foo:444')
        + api.cq_deps.details('foo:444', status='MERGED', project='ham')
        + api.roll_util.noop_roll('applying foo:444.')
        + api.auto_roller.dry_run_success()
    )

    # CL 2000 requires CL 444 which is forbidden.
    yield (
        requires_test('with-requires-forbidden', 'foo:444')
        + api.cq_deps.forbidden('foo:444')
        + api.auto_roller.dry_run_success()
    )

    # CL 2000 requires CL 444 which is not in this checkout.
    yield (
        requires_test('with-requires-not-in-checkout', 'foo:444')
        + api.cq_deps.details(
            'foo:444', status='MERGED', project='not-in-this-checkout',
        )
        + api.auto_roller.dry_run_success()
    )

    # CL 2000 requires CL 444 in ham which requires CL 555 in eggs.
    yield (
        requires_test('with-requires-transitive', 'foo:444')
        + api.cq_deps.details(
            'foo:444',
            status='MERGED',
            project='ham',
            message='Requires: foo:555',
        )
        + api.roll_util.commit_data(
            'ham', api.roll_util.commit('2' * 40), prefix='applying foo:444.',
        )
        + api.roll_util.forward_roll('applying foo:444.')
        + api.cq_deps.details('foo:555', status='MERGED', project='eggs')
        + api.roll_util.commit_data(
            'eggs', api.roll_util.commit('2' * 40), prefix='applying foo:555.',
        )
        + api.roll_util.forward_roll('applying foo:555.')
        + api.auto_roller.dry_run_success()
    )

    # CL 2000 requires CL 444 in ham which requires CL 2000.
    yield (
        requires_test('with-requires-loop', 'foo:444')
        + api.cq_deps.details(
            'foo:444',
            status='MERGED',
            project='ham',
            message='Requires: foo:2000',
        )
        + api.roll_util.commit_data(
            'ham', api.roll_util.commit('2' * 40), prefix='applying foo:444.',
        )
        + api.roll_util.forward_roll('applying foo:444.')
        + api.auto_roller.dry_run_success()
    )

    # CL 2000 requires CL 444 in ham and CL 555 in ham, both of which are
    # submitted.
    def parent_child_test(*args, **kwargs):
        return (
            requires_test(*args, **kwargs)
            + api.cq_deps.details('foo:444', status='MERGED', project='ham',)
            + api.roll_util.commit_data(
                'ham',
                api.roll_util.commit('4' * 40),
                prefix='applying foo:444.',
            )
            + api.roll_util.forward_roll('applying foo:444.')
            + api.cq_deps.details('foo:555', status='MERGED', project='ham',)
        )

    # CL 2000 requires CL 444 in ham and CL 555 in ham, both of which are
    # submitted. CL 444 is a parent of CL 555.
    yield (
        parent_child_test('with-requires-child', 'foo:444', 'foo:555')
        + api.roll_util.forward_roll('applying foo:555.')
        + api.roll_util.commit_data(
            'ham', api.roll_util.commit('5' * 40), prefix='applying foo:555.',
        )
        + api.auto_roller.dry_run_success()
    )

    # CL 2000 requires CL 444 in ham and CL 555 in ham, both of which are
    # submitted. CL 555 is a parent of CL 444.
    yield (
        parent_child_test('with-requires-parent', 'foo:444', 'foo:555')
        + api.roll_util.backward_roll('applying foo:555.')
        + api.auto_roller.dry_run_success()
    )
