#!/usr/bin/env python
#
# ======- git-llvm - LLVM Git Help Integration ---------*- python -*--========#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ==------------------------------------------------------------------------==#

"""
git-llvm integration
====================

This file provides integration for git.
"""

from __future__ import print_function
import argparse
import collections
import contextlib
import errno
import os
import re
import subprocess
import sys
import tempfile
import time
assert sys.version_info >= (2, 7)

try:
    dict.iteritems
except AttributeError:
    # Python 3
    def iteritems(d):
        return iter(d.items())
else:
    # Python 2
    def iteritems(d):
        return d.iteritems()

# It's *almost* a straightforward mapping from the monorepo to svn...
GIT_TO_SVN_DIR = {
    d: (d + '/trunk')
    for d in [
        'clang-tools-extra',
        'compiler-rt',
        'debuginfo-tests',
        'dragonegg',
        'klee',
        'libclc',
        'libcxx',
        'libcxxabi',
        'libunwind',
        'lld',
        'lldb',
        'llgo',
        'llvm',
        'openmp',
        'parallel-libs',
        'polly',
        'pstl',
    ]
}
GIT_TO_SVN_DIR.update({'clang': 'cfe/trunk'})
GIT_TO_SVN_DIR.update({'': 'monorepo-root/trunk'})

VERBOSE = False
QUIET = False
dev_null_fd = None


def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)


def log(*args, **kwargs):
    if QUIET:
        return
    print(*args, **kwargs)


def log_verbose(*args, **kwargs):
    if not VERBOSE:
        return
    print(*args, **kwargs)


def die(msg):
    eprint(msg)
    sys.exit(1)


def split_first_path_component(d):
    # Assuming we have a git path, it'll use slashes even on windows...I hope.
    if '/' in d:
        return d.split('/', 1)
    else:
        return (d, None)


def get_dev_null():
    """Lazily create a /dev/null fd for use in shell()"""
    global dev_null_fd
    if dev_null_fd is None:
        dev_null_fd = open(os.devnull, 'w')
    return dev_null_fd


def shell(cmd, strip=True, cwd=None, stdin=None, die_on_failure=True,
          ignore_errors=False, text=True):
    log_verbose('Running in %s: %s' % (cwd, ' '.join(cmd)))

    err_pipe = subprocess.PIPE
    if ignore_errors:
        # Silence errors if requested.
        err_pipe = get_dev_null()

    start = time.time()
    p = subprocess.Popen(cmd, cwd=cwd, stdout=subprocess.PIPE, stderr=err_pipe,
                         stdin=subprocess.PIPE,
                         universal_newlines=text)
    stdout, stderr = p.communicate(input=stdin)
    elapsed = time.time() - start

    log_verbose('Command took %0.1fs' % elapsed)

    if p.returncode == 0 or ignore_errors:
        if stderr and not ignore_errors:
            eprint('`%s` printed to stderr:' % ' '.join(cmd))
            eprint(stderr.rstrip())
        if strip:
            if text:
                stdout = stdout.rstrip('\r\n')
            else:
                stdout = stdout.rstrip(b'\r\n')
        if VERBOSE:
            for l in stdout.splitlines():
                log_verbose("STDOUT: %s" % l)
        return stdout
    err_msg = '`%s` returned %s' % (' '.join(cmd), p.returncode)
    eprint(err_msg)
    if stderr:
        eprint(stderr.rstrip())
    if die_on_failure:
        sys.exit(2)
    raise RuntimeError(err_msg)


def git(*cmd, **kwargs):
    return shell(['git'] + list(cmd), **kwargs)


def svn(cwd, *cmd, **kwargs):
    return shell(['svn'] + list(cmd), cwd=cwd, **kwargs)

def program_exists(cmd):
    if sys.platform == 'win32' and not cmd.endswith('.exe'):
        cmd += '.exe'
    for path in os.environ["PATH"].split(os.pathsep):
        if os.access(os.path.join(path, cmd), os.X_OK):
            return True
    return False

def get_default_rev_range():
    # Get the branch tracked by the current branch, as set by
    # git branch --set-upstream-to  See http://serverfault.com/a/352236/38694.
    cur_branch = git('rev-parse', '--symbolic-full-name', 'HEAD')
    upstream_branch = git('for-each-ref', '--format=%(upstream:short)',
                          cur_branch)
    if not upstream_branch:
        upstream_branch = 'origin/master'

    # Get the newest common ancestor between HEAD and our upstream branch.
    upstream_rev = git('merge-base', 'HEAD', upstream_branch)
    return '%s..' % upstream_rev


def get_revs_to_push(rev_range):
    if not rev_range:
        rev_range = get_default_rev_range()
    # Use git show rather than some plumbing command to figure out which revs
    # are in rev_range because it handles single revs (HEAD^) and ranges
    # (foo..bar) like we want.
    revs = git('show', '--reverse', '--quiet',
               '--pretty=%h', rev_range).splitlines()
    if not revs:
        die('Nothing to push: No revs in range %s.' % rev_range)
    return revs


def clean_svn(svn_repo):
    svn(svn_repo, 'revert', '-R', '.')

    # Unfortunately it appears there's no svn equivalent for git clean, so we
    # have to do it ourselves.
    for line in svn(svn_repo, 'status', '--no-ignore').split('\n'):
        if not line.startswith('?'):
            continue
        filename = line[1:].strip()
        os.remove(os.path.join(svn_repo, filename))


def svn_init(svn_root):
    if not os.path.exists(svn_root):
        log('Creating svn staging directory: (%s)' % (svn_root))
        os.makedirs(svn_root)
        svn(svn_root, 'checkout', '--depth=empty',
            'https://llvm.org/svn/llvm-project/', '.')
        log("svn staging area ready in '%s'" % svn_root)
    if not os.path.isdir(svn_root):
        die("Can't initialize svn staging dir (%s)" % svn_root)


def fix_eol_style_native(rev, svn_sr_path, files):
    """Fix line endings before applying patches with Unix endings

    SVN on Windows will check out files with CRLF for files with the
    svn:eol-style property set to "native". This breaks `git apply`, which
    typically works with Unix-line ending patches. Work around the problem here
    by doing a dos2unix up front for files with svn:eol-style set to "native".
    SVN will not commit a mass line ending re-doing because it detects the line
    ending format for files with this property.
    """
    # Skip files that don't exist in SVN yet.
    files = [f for f in files if os.path.exists(os.path.join(svn_sr_path, f))]
    # Use ignore_errors because 'svn propget' prints errors if the file doesn't
    # have the named property. There doesn't seem to be a way to suppress that.
    eol_props = svn(svn_sr_path, 'propget', 'svn:eol-style', *files,
                    ignore_errors=True)
    crlf_files = []
    if len(files) == 1:
        # No need to split propget output on ' - ' when we have one file.
        if eol_props.strip() in ['native', 'CRLF']:
            crlf_files = files
    else:
        for eol_prop in eol_props.split('\n'):
            # Remove spare CR.
            eol_prop = eol_prop.strip('\r')
            if not eol_prop:
                continue
            prop_parts = eol_prop.rsplit(' - ', 1)
            if len(prop_parts) != 2:
                eprint("unable to parse svn propget line:")
                eprint(eol_prop)
                continue
            (f, eol_style) = prop_parts
            if eol_style == 'native':
                crlf_files.append(f)
    if crlf_files:
        # Reformat all files with native SVN line endings to Unix format. SVN
        # knows files with native line endings are text files. It will commit
        # just the diff, and not a mass line ending change.
        shell(['dos2unix'] + crlf_files, ignore_errors=True, cwd=svn_sr_path)

def split_subrepo(f):
    # Given a path, splits it into (subproject, rest-of-path). If the path is
    # not in a subproject, returns ('', full-path).

    subproject, remainder = split_first_path_component(f)

    if subproject in GIT_TO_SVN_DIR:
        return subproject, remainder
    else:
        return '', f

def get_all_parent_dirs(name):
    parts = []
    head, tail = os.path.split(name)
    while head:
        parts.append(head)
        head, tail = os.path.split(head)
    return parts

def svn_push_one_rev(svn_repo, rev, dry_run):
    files = git('diff-tree', '--no-commit-id', '--name-only', '-r',
                rev).split('\n')
    if not files:
        raise RuntimeError('Empty diff for rev %s?' % rev)

    # Split files by subrepo
    subrepo_files = collections.defaultdict(list)
    for f in files:
        subrepo, remainder = split_subrepo(f)
        subrepo_files[subrepo].append(remainder)

    status = svn(svn_repo, 'status', '--no-ignore')
    if status:
        die("Can't push git rev %s because svn status is not empty:\n%s" %
            (rev, status))

    svn_dirs_to_update = set()
    for sr, files in iteritems(subrepo_files):
        svn_sr_path = GIT_TO_SVN_DIR[sr]
        for f in files:
            svn_dirs_to_update.add(
                os.path.dirname(os.path.join(svn_sr_path, f)))

    # We also need to svn update any parent directories which are not yet present
    parent_dirs = set()
    for dir in svn_dirs_to_update:
        parent_dirs.update(get_all_parent_dirs(dir))
    parent_dirs = set(dir for dir in parent_dirs
                      if not os.path.exists(os.path.join(svn_repo, dir)))
    svn_dirs_to_update.update(parent_dirs)

    # Sort by length to ensure that the parent directories are passed to svn
    # before child directories.
    sorted_dirs_to_update = sorted(svn_dirs_to_update, key=len)

    # SVN update only in the affected directories.
    svn(svn_repo, 'update', '--depth=files', *sorted_dirs_to_update)

    for sr, files in iteritems(subrepo_files):
        svn_sr_path = os.path.join(svn_repo, GIT_TO_SVN_DIR[sr])
        if os.name == 'nt':
            fix_eol_style_native(rev, svn_sr_path, files)
        # We use text=False (and pass '--binary') so that we can get an exact
        # diff that can be passed as-is to 'git apply' without any line ending,
        # encoding, or other mangling.
        diff = git('show', '--binary', rev, '--',
                   *(os.path.join(sr, f) for f in files),
                   strip=False, text=False)
        # git is the only thing that can handle its own patches...
        if sr == '':
            prefix_strip = '-p1'
        else:
            prefix_strip = '-p2'
        try:
            shell(['git', 'apply', prefix_strip, '-'], cwd=svn_sr_path,
                  stdin=diff, die_on_failure=False, text=False)
        except RuntimeError as e:
            eprint("Patch doesn't apply: maybe you should try `git pull -r` "
                   "first?")
            sys.exit(2)

    status_lines = svn(svn_repo, 'status', '--no-ignore').split('\n')

    for l in (l for l in status_lines if (l.startswith('?') or
                                          l.startswith('I'))):
        svn(svn_repo, 'add', '--no-ignore', l[1:].strip())
    for l in (l for l in status_lines if l.startswith('!')):
        svn(svn_repo, 'remove', l[1:].strip())

    # Now we're ready to commit.
    commit_msg = git('show', '--pretty=%B', '--quiet', rev)
    if not dry_run:
        log(svn(svn_repo, 'commit', '-m', commit_msg, '--force-interactive'))
        log('Committed %s to svn.' % rev)
    else:
        log("Would have committed %s to svn, if this weren't a dry run." % rev)


def cmd_push(args):
    '''Push changes back to SVN: this is extracted from Justin Lebar's script
    available here: https://github.com/jlebar/llvm-repo-tools/

    Note: a current limitation is that git does not track file rename, so they
    will show up in SVN as delete+add.
    '''
    # Get the git root
    git_root = git('rev-parse', '--show-toplevel')
    if not os.path.isdir(git_root):
        die("Can't find git root dir")

    # Push from the root of the git repo
    os.chdir(git_root)

    # We need a staging area for SVN, let's hide it in the .git directory.
    dot_git_dir = git('rev-parse', '--git-common-dir')
    svn_root = os.path.join(dot_git_dir, 'llvm-upstream-svn')
    svn_init(svn_root)

    rev_range = args.rev_range
    dry_run = args.dry_run
    revs = get_revs_to_push(rev_range)
    log('Pushing %d commit%s:\n%s' %
        (len(revs), 's' if len(revs) != 1
         else '', '\n'.join('  ' + git('show', '--oneline', '--quiet', c)
                            for c in revs)))
    for r in revs:
        clean_svn(svn_root)
        svn_push_one_rev(svn_root, r, dry_run)


if __name__ == '__main__':
    if not program_exists('svn'):
        die('error: git-llvm needs svn command, but svn is not installed.')

    argv = sys.argv[1:]
    p = argparse.ArgumentParser(
        prog='git llvm', formatter_class=argparse.RawDescriptionHelpFormatter,
        description=__doc__)
    subcommands = p.add_subparsers(title='subcommands',
                                   description='valid subcommands',
                                   help='additional help')
    verbosity_group = p.add_mutually_exclusive_group()
    verbosity_group.add_argument('-q', '--quiet', action='store_true',
                                 help='print less information')
    verbosity_group.add_argument('-v', '--verbose', action='store_true',
                                 help='print more information')

    parser_push = subcommands.add_parser(
        'push', description=cmd_push.__doc__,
        help='push changes back to the LLVM SVN repository')
    parser_push.add_argument(
        '-n',
        '--dry-run',
        dest='dry_run',
        action='store_true',
        help='Do everything other than commit to svn.  Leaves junk in the svn '
        'repo, so probably will not work well if you try to commit more '
        'than one rev.')
    parser_push.add_argument(
        'rev_range',
        metavar='GIT_REVS',
        type=str,
        nargs='?',
        help="revs to push (default: everything not in the branch's "
        'upstream, or not in origin/master if the branch lacks '
        'an explicit upstream)')
    parser_push.set_defaults(func=cmd_push)
    args = p.parse_args(argv)
    VERBOSE = args.verbose
    QUIET = args.quiet

    # Dispatch to the right subcommand
    args.func(args)
