# 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 project in an Android Repo Tool workspace."""

import collections
import re
import xml.etree.ElementTree

from PB.recipes.pigweed.repo_roller import InputProperties
from PB.recipe_modules.pigweed.checkout.options import (
    Options as CheckoutOptions,
)
from six.moves import urllib

DEPS = [
    'fuchsia/auto_roller',
    'fuchsia/sso',
    'fuchsia/status_check',
    'pigweed/checkout',
    'pigweed/roll_util',
    'recipe_engine/buildbucket',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]

PROPERTIES = InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"


class _TreeBuilder(xml.etree.ElementTree.TreeBuilder):
    def comment(self, data):
        self.start(xml.etree.ElementTree.Comment, {})
        self.data(data)
        self.end(xml.etree.ElementTree.Comment)


def _is_branch(revision):
    """Return True if revision appears to be a branch name."""
    if re.search(r'^[0-9a-fA-F]{40}$', revision):
        return False
    return not revision.startswith('refs/tags/')


# ElementTree orders attributes differently in Python 2 and 3, but if given
# attributes in a specific order it preserves that order.
def _order_attributes(root):
    for el in root.iter():
        if len(el.attrib) > 1:
            new_attrib = sorted(el.attrib.items())
            el.attrib.clear()
            el.attrib.update(new_attrib)


def RunSteps(api, props):  # pylint: disable=invalid-name
    path_to_update = str(props.path_to_update)
    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)
    filepath = checkout.root.join(checkout.options.manifest_file)

    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)

    tree = _TreeBuilder()
    parser = xml.etree.ElementTree.XMLParser(target=tree)
    parser.feed(api.file.read_text('read manifest', filepath))
    parser.close()
    root = tree.close()

    defaults = {}
    for default in root.findall('default'):
        defaults.update(default.attrib)

    remotes = {}
    for rem in root.findall('remote'):
        remotes[rem.attrib['name']] = rem.attrib

    # Search for path_to_update and check the repository it refers to matches
    # the triggering repository. This check is mostly a config check and
    # shouldn't be triggered in real runs unless somebody moves around project
    # paths in the manifest without updating the builder definition.
    paths_found = []
    proj = None
    proj_attrib = {}
    for proj in root.findall('project'):
        # Sometimes projects don't define something in which case we need to
        # fall back on the remote specified by the project or the default for
        # the entire manifest.
        proj_attrib = {}
        proj_attrib.update(defaults)
        remote_name = proj.attrib.get('remote', defaults.get('remote', None))
        assert remote_name
        proj_attrib.update(remotes[remote_name])
        proj_attrib.update(proj.attrib)
        proj_attrib['fetch'] = api.sso.sso_to_https(proj_attrib['fetch'])

        # Apparently if path is left off name is used. This is mildly
        # infuriating, but easy to work around.
        if 'path' not in proj_attrib:
            proj_attrib['path'] = proj_attrib['name']

        paths_found.append(proj_attrib['path'])
        if proj_attrib['path'] == path_to_update:
            fetch_host = proj_attrib['fetch'].strip('/')
            if fetch_host.startswith('..'):
                parsed = urllib.parse.urlparse(checkout.options.remote)
                fetch_host = '{}://{}{}'.format(
                    parsed.scheme, parsed.netloc, fetch_host[2:]
                )

            manifest_remote = fetch_host + '/' + proj_attrib['name'].strip('/')
            if bb_remote and not checkout.remotes_equivalent(
                manifest_remote, bb_remote
            ):
                raise api.step.StepFailure(
                    "repo paths don't match: {} from manifest "
                    "and {} from buildbucket".format(manifest_remote, bb_remote)
                )
            break

        # Reset proj_attrib to None if this entry wasn't a match, so if this is
        # the last iteration the condition a few lines down will work.
        proj_attrib = {}

    if not proj_attrib:
        raise api.step.StepFailure(
            'cannot find "{}" in manifest (found {})'.format(
                path_to_update, ', '.join('"{}"'.format(x) for x in paths_found)
            )
        )

    if 'upstream' in proj_attrib:
        proj_branch = proj_attrib['upstream']
    elif 'revision' in proj_attrib and _is_branch(proj_attrib['revision']):
        proj_branch = proj_attrib['revision']
    else:
        proj_branch = 'main'

    # If we still don't have a revision then it wasn't in the trigger. (Perhaps
    # this was manually triggered.) In this case we need to determine the
    # latest revision of this repository. The use_trigger flag should have no
    # effect but using it to be explicit. Checking out even if not needed so
    # commit messages can be collected later.
    proj_dir = api.path['start_dir'].join('project')
    proj_checkout = api.checkout(
        CheckoutOptions(
            remote=manifest_remote, branch=proj_branch, use_trigger=False
        ),
        root=proj_dir,
    )
    if new_revision is None:
        new_revision = api.checkout.get_revision(proj_dir)

    assert new_revision
    new_revision = str(new_revision)

    # If upstream not set we may be transitioning from tracking a branch to
    # rolling. In that case set upstream to be the revision, but only if the
    # revision appears to be a branch.
    if 'upstream' not in proj_attrib:
        if _is_branch(proj_attrib['revision']):
            # Explicitly update both proj.attrib and proj_attrib to minimize
            # confusion if these statements are moved around later.
            proj.attrib['upstream'] = proj_attrib['revision']
            proj_attrib['upstream'] = proj.attrib['upstream']
        else:
            raise api.step.StepFailure(
                'upstream not set and revision is not a branch, aborting'
            )

    old_revision = proj_attrib['revision']
    # Explicitly update both proj.attrib and proj_attrib to minimize confusion.
    proj_attrib['revision'] = proj.attrib['revision'] = new_revision

    direction = api.roll_util.Direction.FORWARD
    if not _is_branch(old_revision):
        direction = api.roll_util.get_roll_direction(
            proj_dir, old_revision, new_revision
        )

    if not api.roll_util.can_roll(direction):
        api.roll_util.skip_roll_step(
            manifest_remote, old_revision, new_revision
        )
        return

    _order_attributes(root)

    api.file.write_text(
        'write manifest',
        filepath,
        '<?xml version="1.0" encoding="UTF-8"?>\n{}\n'.format(
            xml.etree.ElementTree.tostring(root).decode(),
        ),
    )

    roll = api.roll_util.Roll(
        project_name=path_to_update,
        old_revision=old_revision,
        new_revision=new_revision,
        proj_dir=proj_dir,
        direction=direction,
    )

    cc = set()
    authors = api.roll_util.authors(roll)
    if cc_authors_on_rolls:
        cc.update(authors)
    if cc_reviewers_on_rolls:
        cc.update(api.roll_util.reviewers(roll))

    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(roll),
        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 properties(api, path, dry_run=True, equivalent_remotes=(), **kwargs):
        props = api.checkout.git_properties(
            remote='https://host.googlesource.com/manifest',
            equivalent_remotes=equivalent_remotes,
            match_branch=True,
        )
        props['forge_author'] = True
        props['path_to_update'] = path
        props['dry_run'] = dry_run
        props.update(**kwargs)
        return api.properties(**props)

    def read_step_data():
        return api.step_data(
            'read manifest',
            api.file.read_text(
                """
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <!-- single-line comment -->
  <remote name="foo" fetch="sso://foo" review="sso://foo" />
  <remote name="bar" fetch="sso://bar" review="sso://bar" />
  <remote name="host" fetch=".." review="sso://host" />
  <remote name="dotdot-prefix" fetch="../prefix" review="sso://host/prefix" />
  <remote name="host-prefix" fetch="sso://host/prefix"
    review="sso://host/prefix" />
  <default remote="bar" />
  <project name="a" path="a1" remote="foo"
    revision="1111111111111111111111111111111111111111" upstream="main"/>
  <project name="b" path="b2"
    revision="2222222222222222222222222222222222222222" upstream="main"/>
  <!--
  multi
  line
  comment
  -->
  <project name="c" path="c3" revision="main"/>
  <project name="d" path="d4"
    revision="0000000000111111111122222222223333333333"/>
  <project name="e5" revision="refs/tags/e"/>
  <project name="f" path="f6" remote="host" revision="main"/>
  <project name="g" path="g7" remote="dotdot-prefix" revision="main"/>
  <project name="h" path="h8" remote="host-prefix" revision="main"/>
</manifest>
""".lstrip()
            ),
        )

    def commit_data(name):
        return api.roll_util.commit_data(
            name, api.roll_util.commit('a' * 40, 'foo\nbar')
        )

    yield (
        api.status_check.test('success')
        + properties(api, path='a1', cc_authors_on_rolls=True, always_cc=True)
        + api.checkout.ci_test_data(git_repo='https://foo.googlesource.com/a')
        + commit_data('a1')
        + read_step_data()
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('name-not-found', status='failure')
        + properties(api, path='missing')
        + api.checkout.ci_test_data(git_repo='https://bar.googlesource.com/b')
        + read_step_data()
    )

    yield (
        api.status_check.test('equivalent')
        + properties(
            api,
            path='b2',
            equivalent_remotes=(
                (
                    'https://equiv.googlesource.com/b',
                    'https://bar.googlesource.com/b',
                ),
            ),
            cc_reviewers_on_rolls=True,
        )
        + api.checkout.ci_test_data(git_repo='https://equiv.googlesource.com/b')
        + commit_data('b2')
        + read_step_data()
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('upstream-not-set')
        + properties(api, path='c3')
        + api.checkout.ci_test_data(git_repo='https://bar.googlesource.com/c')
        + commit_data('c3')
        + read_step_data()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test(
            'upstream-not-set-revision-not-branch', status='failure'
        )
        + properties(api, path='d4')
        + api.checkout.ci_test_data(git_repo='https://bar.googlesource.com/c')
        + read_step_data()
    )

    yield (
        api.status_check.test('no-trigger-with-upstream')
        + properties(api, path='a1')
        + commit_data('a1')
        + read_step_data()
        + api.step_data(
            'git log',
            stdout=api.raw_io.output_text('hash-from-special-checkout'),
        )
        + api.roll_util.forward_roll()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('no-trigger-with-revision-branch')
        + properties(api, path='c3')
        + commit_data('c3')
        + read_step_data()
        + api.step_data(
            'git log',
            stdout=api.raw_io.output_text('hash-from-special-checkout'),
        )
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('no-trigger-with-revision-hash', status='failure')
        + properties(api, path='d4')
        + read_step_data()
        + api.step_data(
            'git log',
            stdout=api.raw_io.output_text('hash-from-special-checkout'),
        )
    )

    yield (
        api.status_check.test('no-trigger-with-revision-tag', status='failure')
        + properties(api, path='e5')
        + read_step_data()
        + api.step_data(
            'git log',
            stdout=api.raw_io.output_text('hash-from-special-checkout'),
        )
    )

    yield (
        api.status_check.test('backwards')
        + properties(api, path='a1')
        + api.checkout.ci_test_data(git_repo='https://foo.googlesource.com/a')
        + read_step_data()
        + api.roll_util.backward_roll()
    )

    yield (
        api.status_check.test('host-dot-dot')
        + properties(api, path='f6')
        + api.checkout.ci_test_data(git_repo='https://host.googlesource.com/f')
        + commit_data('f6')
        + read_step_data()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('dotdot-prefix')
        + properties(api, path='g7')
        + api.checkout.ci_test_data(
            git_repo='https://host.googlesource.com/prefix/g'
        )
        + commit_data('g7')
        + read_step_data()
        + api.auto_roller.dry_run_success()
    )

    yield (
        api.status_check.test('host-prefix')
        + properties(api, path='h8')
        + api.checkout.ci_test_data(
            git_repo='https://host.googlesource.com/prefix/h'
        )
        + commit_data('h8')
        + read_step_data()
        + api.auto_roller.dry_run_success()
    )
