# 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(
                    sub.path, 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_emails'] = [x.email for x in cc]
    else:
        roll_kwargs['cc_on_failure_emails'] = [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(
        api.auto_roller.Options(
            remote=checkout.options.remote,
            upstream_ref=checkout.options.branch,
            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
        ),
        repo_dir=checkout.root,
        commit_message=api.roll_util.message(*rolls.values()),
        author_override=author_override,
    )

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