# 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, checkout, path, new_revision):
    with api.context(cwd=checkout.top):
        api.git.update_submodule(paths=(path,))

    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, checkout, 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.
        checkout (CheckoutContext): Checkout-related data.
        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 = 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 checkout.remotes_equivalent(dep.remote, sub.remote):
                continue
            found_dep = True

            with api.step.nest('applying {}'.format(dep.name)) as pres:
                with api.context(cwd=checkout.top):
                    api.git.update_submodule(paths=(sub.relative_path,))

                old_revision = sub.hash
                if sub.relative_path in rolls:
                    old_revision = rolls[sub.relative_path].old_revision
                with api.context(cwd=sub.path):
                    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, checkout, 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

    props.checkout_options.use_trigger = False
    checkout = api.checkout(props.checkout_options)

    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', 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 = checkout.submodules(checkout.root)

    submodule_dir = checkout.root.join(submodule_path)

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

    # If this was triggered by a gitiles poller, check that the triggering
    # repository matches submodule_path.
    if bb_remote:
        if not 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, checkout, 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, checkout, rolls, submodules, gerrit_name)

    cc = set()
    authors = api.roll_util.authors(*rolls.values())
    if cc_authors_on_rolls:
        cc.update(authors)
    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, 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'] = [x.email for x in cc]
    else:
        roll_kwargs['cc_on_failure'] = [x.email for x in cc]

    author_override = None
    with api.step.nest('authors') as pres:
        pres.step_summary_text = repr(authors)
    if len(authors) == 1 and props.forge_author:
        author_override = api.roll_util.fake_author(
            next(iter(authors))
        )._asdict()

    change = api.auto_roller.attempt_roll(
        gerrit_host=checkout.gerrit_host(),
        gerrit_project=checkout.gerrit_project(),
        upstream_ref=checkout.options.branch,
        repo_dir=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,
        author_override=author_override,
        **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['forge_author'] = True
        new_kwargs['dry_run'] = True
        new_kwargs.update(kwargs)
        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)
        + api.roll_util.properties(commit_divider='--divider--')
        + 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

        sub = api.checkout.submodule
        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(
                sub('spam', 'https://foo.googlesource.com/spam', '-'),
                sub('ham', 'https://foo.googlesource.com/ham', '-'),
                sub('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()
    )
