#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This is a tool for picking patches from upstream and applying them."""

"""echo""" "This is a python script! Don't interpret it with bash."
"""exit"""

import argparse
from collections import OrderedDict
import configparser
import functools
import mailbox
import os
import pprint
import re
import signal
import socket
import ssl
import subprocess
import sys
import textwrap
import urllib.request
import xmlrpc.client

errprint = functools.partial(print, file=sys.stderr)

# pylint: disable=line-too-long
# Note: Do not include trailing / in any of these
UPSTREAM_URLS = (
    # Acceptable Linux URLs
    'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git',
    'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git',
    'https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux.git',

    # Acceptible Linux Firmware URLs
    'git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git',
    'https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git',
    'https://kernel.googlesource.com/pub/scm/linux/kernel/git/firmware/linux-firmware.git',

    # Upstream for various other projects
    'git://w1.fi/srv/git/hostap.git',
    'git://git.kernel.org/pub/scm/bluetooth/bluez.git',
    'https://github.com/andersson/qrtr.git',
    'https://review.coreboot.org/flashrom.git'
)

PATCHWORK_URLS = (
    'https://patchwork.kernel.org',
    'https://patchwork.ozlabs.org',
    'https://patchwork.freedesktop.org',
)

COMMIT_MESSAGE_WIDTH = 75

_PWCLIENTRC = os.path.expanduser('~/.pwclientrc')

def _git(args, stdin=None, encoding='utf-8', no_stderr=False):
    """Calls a git subcommand.

    Similar to subprocess.check_output.

    Args:
        args: subcommand + args passed to 'git'.
        stdin: a string or bytes (depending on encoding) that will be passed
            to the git subcommand.
        encoding: either 'utf-8' (default) or None. Override it to None if
            you want both stdin and stdout to be raw bytes.
        no_stderr: If True, we'll eat stderr

    Returns:
        the stdout of the git subcommand, same type as stdin. The output is
        also run through strip to make sure there's no extra whitespace.

    Raises:
        subprocess.CalledProcessError: when return code is not zero.
            The exception has a .returncode attribute.
    """
    return subprocess.run(
        ['git'] + args,
        encoding=encoding,
        input=stdin,
        stdout=subprocess.PIPE,
        stderr=(subprocess.PIPE if no_stderr else None),
        check=True,
    ).stdout.strip()

def _git_returncode(*args, **kwargs):
    """Same as _git, but return returncode instead of stdout.

    Similar to subprocess.call.

    Never raises subprocess.CalledProcessError.
    """
    try:
        _git(*args, **kwargs)
        return 0
    except subprocess.CalledProcessError as e:
        return e.returncode

def _get_conflicts():
    """Report conflicting files."""
    resolutions = ('DD', 'AU', 'UD', 'UA', 'DU', 'AA', 'UU')
    conflicts = []
    output = _git(['status', '--porcelain', '--untracked-files=no'])
    for line in output.splitlines():
        if not line:
            continue
        resolution, name = line.split(None, 1)
        if resolution in resolutions:
            conflicts.append('   ' + name)
    if not conflicts:
        return ''
    return '\nConflicts:\n%s\n' % '\n'.join(conflicts)

def _find_upstream_remote(urls):
    """Find a remote pointing to an upstream repository."""
    for remote in _git(['remote']).splitlines():
        try:
            if _git(['remote', 'get-url', remote]).rstrip('/') in urls:
                return remote
        except subprocess.CalledProcessError:
            # Kinda weird, get-url failing on an item that git just gave us.
            continue
    return None

def _pause_for_merge(conflicts):
    """Pause and go in the background till user resolves the conflicts."""

    git_root = _git(['rev-parse', '--show-toplevel'])
    previous_head_hash = _git(['rev-parse', 'HEAD'])

    paths = (
        os.path.join(git_root, '.git', 'rebase-apply'),
        os.path.join(git_root, '.git', 'CHERRY_PICK_HEAD'),
    )
    for path in paths:
        if os.path.exists(path):
            errprint('Found "%s".' % path)
            errprint(conflicts)
            errprint('Please resolve the conflicts and restart the '
                     'shell job when done. Kill this job if you '
                     'aborted the conflict.')
            os.kill(os.getpid(), signal.SIGTSTP)

    # Check the conflicts actually got resolved. Otherwise we'll end up
    # modifying the wrong commit message and probably confusing people.
    while previous_head_hash == _git(['rev-parse', 'HEAD']):
        errprint('Error: no new commit has been made. Did you forget to run '
                 '`git am --continue` or `git cherry-pick --continue`?')
        errprint('Please create a new commit and restart the shell job (or kill'
                 ' it if you aborted the conflict).')
        os.kill(os.getpid(), signal.SIGTSTP)

def _get_pw_url(project):
    """Retrieve the patchwork server URL from .pwclientrc.

    Args:
        project: patchwork project name; if None, we retrieve the default
            from pwclientrc
    """
    config = configparser.ConfigParser()
    config.read([_PWCLIENTRC])

    if project is None:
        try:
            project = config.get('options', 'default')
        except (configparser.NoSectionError, configparser.NoOptionError) as e:
            errprint('Error: no default patchwork project found in %s. (%r)'
                     % (_PWCLIENTRC, e))
            sys.exit(1)

    if not config.has_option(project, 'url'):
        errprint("Error: patchwork URL not found for project '%s'" % project)
        sys.exit(1)

    url = config.get(project, 'url')
    # Strip trailing 'xmlrpc' and/or trailing slash.
    return re.sub('/(xmlrpc/)?$', '', url)

def _wrap_commit_line(prefix, content):
    line = prefix + content
    indent = ' ' * len(prefix)

    ret = textwrap.fill(line, COMMIT_MESSAGE_WIDTH, subsequent_indent=indent)
    return ret[len(prefix):]

def _get_patch_from_message_id(args, message_id):
    for (url_template, mbox_suffix) in [
        ('https://lore.kernel.org/r/%s', 'raw'),
        # hostap project (and others) are here, but not kernel.org.
        ('https://marc.info/?i=%s', None),
        # public-inbox comes last as a "default"; it has a nice error page
        # pointing to other redirectors, even if it doesn't have what
        # you're looking for directly.
        ('https://public-inbox.org/git/%s', None),
    ]:
        this_url = url_template % message_id
        if args['debug']:
            print('Probing archive for message at: %s' % this_url)
        try:
            opener = urllib.request.urlopen(this_url)

            # To actually get the patch from lore.kernel.org we need to:
            # - Let it redirect us to an actual list it's tracking.
            # - Add the "raw" suffix
            if (opener.url != this_url) and mbox_suffix:
                opener = urllib.request.urlopen(opener.url + mbox_suffix)
        except urllib.error.HTTPError as e:
            # Skip all HTTP errors. We can expect 404 for archives that
            # don't have this MessageId, or 300 for public-inbox ("not
            # found, but try these other redirects"). It's less clear what
            # to do with transitory (or is it permanent?) server failures.
            if args['debug']:
                print('Skipping URL %s, error: %s' % (this_url, e))
            continue
        # Success!
        if args['debug']:
            print('Found at %s' % this_url)
        return this_url, opener.read()
    errprint(
        "WARNING: couldn't find working MessageId URL; "
        'defaulting to "%s"' % this_url)
    return this_url, None

def _pick_fromlist(url, patch_id, args, message_id=None):
    if args['tag'] is None:
        args['tag'] = 'FROMLIST: '

    if patch_id is not None:
        try:
            opener = urllib.request.urlopen('%s/patch/%s/mbox' % (url, patch_id))
        except urllib.error.HTTPError as e:
            errprint('Error: could not download patch: %s' % e)
            sys.exit(1)
        patch_contents = opener.read()

        if not patch_contents:
            errprint('Error: No patch content found')
            sys.exit(1)

        message_id = mailbox.Message(patch_contents)['Message-Id']
        message_id = re.sub('^<|>$', '', message_id.strip())
        alt_url = None
    elif message_id is not None:
        alt_url, patch_contents = _get_patch_from_message_id(args, message_id)
        if patch_contents is None:
            errprint('Error: could not find patch based on message id')
            sys.exit(1)
    else:
        errprint('Error: Need a message ID or a patchwork ID')
        sys.exit(1)

    if args['source_line'] is None:
        if alt_url is None:
            alt_url, _ = _get_patch_from_message_id(args, message_id)

        if patch_id is not None:
            args['source_line'] = '(am from %s/patch/%s/)' % (url, patch_id)
            args['source_line'] += '\n(also found at %s)' % alt_url
        else:
            args['source_line'] = '(am from %s)' % alt_url

    # Auto-snarf the Change-Id if it was encoded into the Message-Id.
    mo = re.match(r'.*(I[a-f0-9]{40})@changeid$', message_id)
    if mo and args['changeid'] is None:
        args['changeid'] = mo.group(1)

    if args['replace']:
        _git(['reset', '--hard', 'HEAD~1'])

    return _git_returncode(['am', '-3'], stdin=patch_contents, encoding=None)

def _match_patchwork(match, args):
    """Match location: pw://### or pw://PROJECT/###."""
    pw_project = match.group(2)
    patch_id = match.group(3)

    if args['debug']:
        print('_match_patchwork: pw_project=%s, patch_id=%s' %
              (pw_project, patch_id))

    url = _get_pw_url(pw_project)
    return _pick_fromlist(url, patch_id, args)

def _match_msgid(match, args):
    """Match location: msgid://MSGID."""
    msgid = match.group(1)

    if args['debug']:
        print('_match_msgid: message_id=%s' % (msgid))

    url = None
    for url in PATCHWORK_URLS:
        rpc = xmlrpc.client.ServerProxy(url + '/xmlrpc/')
        try:
            # Patchwork requires the brackets so force it
            res = rpc.patch_list({'msgid': '<' + msgid + '>'})
        except ssl.SSLCertVerificationError:
            errprint('Error: server "%s" gave an SSL error, skipping' % url)
            continue
        except socket.gaierror as e:
            errprint('Error: server "%s" gave socket error "%s", skipping' % (url, e))
        if res:
            patch_id = res[0]['id']
            break
    else:
        # We can't find a patch ID for this message but we won't give up.
        # Some patches might not be on any (known) patchwork servers but
        # can still be found on mailing list archives.
        patch_id = None

    return _pick_fromlist(url, patch_id, args, msgid)

def _upstream(commit, urls, args):
    if args['debug']:
        print('_upstream: commit=%s' % commit)

    # Confirm an upstream remote is setup.
    remote = _find_upstream_remote(urls)
    if not remote:
        errprint('Error: need a valid upstream remote')
        sys.exit(1)

    branches = ['main', 'master']
    for branch in branches:
        remote_ref = '%s/%s' % (remote, branch)
        try:
            _git(['merge-base', '--is-ancestor', commit, remote_ref],
                 no_stderr=True)
        except subprocess.CalledProcessError:
            continue
        break
    else:
        errprint('Error: Commit not in %s, branches: %s' % (
                 remote, ', '.join(branches)))
        sys.exit(1)

    if args['source_line'] is None:
        commit = _git(['rev-parse', commit])
        args['source_line'] = ('(cherry picked from commit %s)' %
                               (commit))
    if args['tag'] is None:
        args['tag'] = 'UPSTREAM: '

    if args['replace']:
        _git(['reset', '--hard', 'HEAD~1'])

    return _git_returncode(['cherry-pick', commit])

def _match_upstream(match, args):
    """Match location: linux://HASH and upstream://HASH."""
    commit = match.group(1)
    return _upstream(commit, urls=UPSTREAM_URLS, args=args)

def _match_fromgit(match, args):
    """Match location: git://remote/branch/HASH."""
    remote = match.group(2)
    branch = match.group(3)
    commit = match.group(4)

    if args['debug']:
        print('_match_fromgit: remote=%s branch=%s commit=%s' %
              (remote, branch, commit))

    try:
        _git(['merge-base', '--is-ancestor', commit,
              '%s/%s' % (remote, branch)])
    except subprocess.CalledProcessError:
        errprint('Error: Commit not in %s/%s' % (remote, branch))
        sys.exit(1)

    url = _git(['remote', 'get-url', remote])

    if args['source_line'] is None:
        commit = _git(['rev-parse', commit])
        args['source_line'] = (
            '(cherry picked from commit %s\n %s %s)' % (commit, url, branch))
    if args['tag'] is None:
        args['tag'] = 'FROMGIT: '

    if args['replace']:
        _git(['reset', '--hard', 'HEAD~1'])

    return _git_returncode(['cherry-pick', commit])

def _match_gitfetch(match, args):
    """Match location: (git|https)://repoURL#branch/HASH."""
    remote = match.group(1)
    branch = match.group(3)
    commit = match.group(4)

    if args['debug']:
        print('_match_gitfetch: remote=%s branch=%s commit=%s' %
              (remote, branch, commit))

    try:
        _git(['fetch', remote, branch])
    except subprocess.CalledProcessError:
        errprint('Error: Branch not in %s' % remote)
        sys.exit(1)

    url = remote

    if args['source_line'] is None:
        commit = _git(['rev-parse', commit])
        args['source_line'] = (
            '(cherry picked from commit %s\n %s %s)' % (commit, url, branch))
    if args['tag'] is None:
        args['tag'] = 'FROMGIT: '

    if args['replace']:
        _git(['reset', '--hard', 'HEAD~1'])

    return _git_returncode(['cherry-pick', commit])

def _match_gitweb(match, args):
    """Match location: https://repoURL/commit/?h=branch&id=HASH."""
    remote = match.group(1)
    branch = match.group(2)
    commit = match.group(3)

    if args['debug']:
        print('_match_gitweb: remote=%s branch=%s commit=%s' %
              (remote, branch, commit))

    try:
        _git(['fetch', remote, branch])
    except subprocess.CalledProcessError:
        errprint('Error: Branch not in %s' % remote)
        sys.exit(1)

    url = remote

    if args['source_line'] is None:
        commit = _git(['rev-parse', commit])
        args['source_line'] = (
            '(cherry picked from commit %s\n %s %s)' % (commit, url, branch))
    if args['tag'] is None:
        args['tag'] = 'FROMGIT: '

    if args['replace']:
        _git(['reset', '--hard', 'HEAD~1'])

    return _git_returncode(['cherry-pick', commit])

def _remove_dup_bugs(bugs):
    """Remove the duplicated bugs from a string keeping the original order."""

    # Standardize all the spacing around bugs
    bugs = re.sub(r'\s*,\s*', ', ', bugs)

    # Create a list of bugs
    bugs = bugs.split(', ')

    # Remove duplicates keeping order
    bugs = list(OrderedDict.fromkeys(bugs).keys())

    # Convert into a string again
    bugs = ', '.join(bugs)

    return bugs

def main(args):
    """This is the main entrypoint for fromupstream.

    Args:
        args: sys.argv[1:]

    Returns:
        An int return code.
    """
    parser = argparse.ArgumentParser()

    parser.add_argument('--bug', '-b', action='append', default=[],
                        type=str, help='BUG= line')
    parser.add_argument('--test', '-t', action='append', default=[],
                        type=str, help='TEST= line')
    parser.add_argument('--crbug', action='append', default=[],
                        type=int, help='BUG=chromium: line')
    parser.add_argument('--buganizer', action='append', default=[],
                        type=int, help='BUG=b: line')
    parser.add_argument('--changeid', '-c',
                        help='Overrides the gerrit generated Change-Id line')
    parser.add_argument('--cqdepend',
                        type=str, help='Cq-Depend: line')

    parser.add_argument('--replace', '-r',
                        action='store_true',
                        help='Replaces the HEAD commit with this one, taking '
                        'its properties(BUG, TEST, Change-Id). Useful for '
                        'updating commits.')
    parser.add_argument('--nosignoff',
                        dest='signoff', action='store_false')
    parser.add_argument('--debug', '-d', action='store_true',
                        help='Prints more verbose logs.')

    parser.add_argument('--tag',
                        help='Overrides the tag from the title')
    parser.add_argument('--source', '-s',
                        dest='source_line', type=str,
                        help='Overrides the source line, last line, ex: '
                        '(am from http://....)')
    parser.add_argument('locations',
                        nargs='+',
                        help='Patchwork ID (pw://### or pw://PROJECT/###, '
                        'where PROJECT is defined in ~/.pwclientrc; if no '
                        'PROJECT is specified, the default is retrieved from '
                        '~/.pwclientrc), '
                        'Message-ID (msgid://MSGID), '
                        'linux commit like linux://HASH, '
                        'upstream commit like upstream://HASH, or '
                        'git reference like git://remote/branch/HASH or '
                        'git://repoURL#branch/HASH or '
                        'https://repoURL#branch/HASH or '
                        'https://repoURL/commit/?h=branch&id=HASH')

    args = vars(parser.parse_args(args))

    cq_depends = [args['cqdepend']] if args['cqdepend'] else []

    bugs = args['bug']
    bugs += ['b:%d' % x for x in args['buganizer']]
    bugs += ['chromium:%d' % x for x in args['crbug']]
    bugs = ', '.join(bugs)
    bugs = _remove_dup_bugs(bugs)
    if bugs:
        bug_lines = [x.strip(' ,') for x in
                     _wrap_commit_line('BUG=', bugs).split('\n')]
    else:
        bug_lines = []

    test_lines = [_wrap_commit_line('TEST=', x) for x in args['test']]

    if args['replace']:
        old_commit_message = _git(['show', '-s', '--format=%B', 'HEAD'])

        # It is possible that multiple Change-Ids are in the commit message
        # (due to cherry picking).  We only want to pull out the first one.
        changeid_match = re.search('^Change-Id: (.*)$',
                                   old_commit_message, re.MULTILINE)
        if args['changeid'] is None and changeid_match:
            args['changeid'] = changeid_match.group(1)

        if not cq_depends:
            cq_depends = re.findall(r'^Cq-Depend:\s+(.*)$',
                                    old_commit_message, re.MULTILINE)

        if not bug_lines:
            bug_lines = re.findall(r'^BUG=(.*)$',
                                   old_commit_message, re.MULTILINE)

        if not test_lines:
            # Note: use (?=...) to avoid to consume the source string
            test_lines = re.findall(r"""
                ^TEST=(.*?)     # Match start from TEST= until
                \n              # (to remove the tailing newlines)
                (?=^$|          # a blank line
                   ^Cq-Depend:| # or Cq-Depend:
                   ^Change-Id:| # or Change-Id:
                   ^BUG=|       # or following BUG=
                   ^TEST=)      # or another TEST=
                """,
                old_commit_message, re.MULTILINE | re.DOTALL | re.VERBOSE)

    if not bug_lines or not test_lines:
        parser.error('BUG=/TEST= lines are required; --replace can help '
                     'automate, or set via --bug/--test')

    if args['debug']:
        pprint.pprint(args)

    re_matches = (
        (re.compile(r'^pw://(([^/]+)/)?(.+)'), _match_patchwork),
        (re.compile(r'^msgid://<?([^>]*)>?'), _match_msgid),
        (re.compile(r'^linux://([0-9a-f]+)'), _match_upstream),
        (re.compile(r'^upstream://([0-9a-f]+)'), _match_upstream),
        (re.compile(r'^(from)?git://([^/\#]+)/([^#]+)/([0-9a-f]+)$'),
         _match_fromgit),
        (re.compile(r'^((git|https)://.+)#(.+)/([0-9a-f]+)$'), _match_gitfetch),
        (re.compile(r'^(https://.+)/commit/\?h=(.+)\&id=([0-9a-f]+)$'), _match_gitweb),
    )

    # Backup user provided parameters
    user_source_line = args['source_line']
    user_tag = args['tag']
    user_changeid = args['changeid']

    for location in args['locations']:
        # Restore user parameters
        args['source_line'] = user_source_line
        args['tag'] = user_tag
        args['changeid'] = user_changeid

        if args['debug']:
            print('location=%s' % location)

        for reg, handler in re_matches:
            match = reg.match(location)
            if match:
                ret = handler(match, args)
                break
        else:
            errprint('Don\'t know what "%s" means.' % location)
            sys.exit(1)

        if ret != 0:
            conflicts = _get_conflicts()
            if args['tag'] == 'UPSTREAM: ':
                args['tag'] = 'BACKPORT: '
            else:
                args['tag'] = 'BACKPORT: ' + args['tag']
            _pause_for_merge(conflicts)
        else:
            conflicts = ''

        # extract commit message
        commit_message = _git(['show', '-s', '--format=%B', 'HEAD'])

        # Remove stray Change-Id, most likely from merge resolution
        commit_message = re.sub(r'Change-Id:.*\n?', '', commit_message)

        # Note the source location before tagging anything else
        commit_message += '\n' + args['source_line']

        # add automatic Change ID, BUG, and TEST (and maybe signoff too) so
        # next commands know where to work on
        commit_message += '\n'
        commit_message += conflicts
        commit_message += '\n'
        commit_message += '\n'.join('BUG=%s' % bug for bug in bug_lines)
        commit_message += '\n'
        commit_message += '\n'.join('TEST=%s' % t for t in test_lines)

        extra = []
        if args['signoff']:
            signoff = 'Signed-off-by: %s <%s>' % (
                    _git(['config', 'user.name']),
                    _git(['config', 'user.email']))
            if not signoff in commit_message.splitlines():
                extra += ['-s']
        _git(['commit'] + extra + ['--amend', '-F', '-'], stdin=commit_message)

        # re-extract commit message
        commit_message = _git(['show', '-s', '--format=%B', 'HEAD'])

        # If we see a "Link: " that seems to point to a Message-Id with an
        # automatic Change-Id we'll snarf it out.
        mo = re.search(r'^Link:.*(I[a-f0-9]{40})@changeid', commit_message,
                       re.MULTILINE)
        if mo and args['changeid'] is None:
            args['changeid'] = mo.group(1)

        # replace changeid if needed
        if args['changeid'] is not None:
            commit_message = re.sub(r'(Change-Id: )(\w+)', r'\1%s' %
                                    args['changeid'], commit_message)
            args['changeid'] = None

        if cq_depends:
            commit_message = re.sub(
                r'(Change-Id: \w+)',
                r'%s\n\1' % '\n'.join('Cq-Depend: %s' % c for c in cq_depends),
                commit_message)

        # decorate it that it's from outside
        commit_message = args['tag'] + commit_message

        # commit everything
        _git(['commit', '--amend', '-F', '-'], stdin=commit_message)

    return 0

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
