#!/usr/bin/env python3
#
# Copyright BitBake Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#

"""git-make-shallow: make the current git repository shallow

Remove the history of the specified revisions, then optionally filter the
available refs to those specified.
"""

import argparse
import collections
import errno
import itertools
import os
import subprocess
import sys
import warnings
warnings.simplefilter("default")

version = 1.0


git_cmd = ['git', '-c', 'safe.bareRepository=all']

def main():
    if sys.version_info < (3, 4, 0):
        sys.exit('Python 3.4 or greater is required')

    git_dir = check_output(git_cmd + ['rev-parse', '--git-dir']).rstrip()
    shallow_file = os.path.join(git_dir, 'shallow')
    if os.path.exists(shallow_file):
        try:
            check_output(git_cmd + ['fetch', '--unshallow'])
        except subprocess.CalledProcessError:
            try:
                os.unlink(shallow_file)
            except OSError as exc:
                if exc.errno != errno.ENOENT:
                    raise

    args = process_args()
    revs = check_output(git_cmd + ['rev-list'] + args.revisions).splitlines()

    make_shallow(shallow_file, args.revisions, args.refs)

    ref_revs = check_output(git_cmd + ['rev-list'] + args.refs).splitlines()
    remaining_history = set(revs) & set(ref_revs)
    for rev in remaining_history:
        if check_output(git_cmd + ['rev-parse', '{}^@'.format(rev)]):
            sys.exit('Error: %s was not made shallow' % rev)

    filter_refs(args.refs)

    if args.shrink:
        shrink_repo(git_dir)
        subprocess.check_call(git_cmd + ['fsck', '--unreachable'])


def process_args():
    # TODO: add argument to automatically keep local-only refs, since they
    # can't be easily restored with a git fetch.
    parser = argparse.ArgumentParser(description='Remove the history of the specified revisions, then optionally filter the available refs to those specified.')
    parser.add_argument('--ref', '-r', metavar='REF', action='append', dest='refs', help='remove all but the specified refs (cumulative)')
    parser.add_argument('--shrink', '-s', action='store_true', help='shrink the git repository by repacking and pruning')
    parser.add_argument('revisions', metavar='REVISION', nargs='+', help='a git revision/commit')
    if len(sys.argv) < 2:
        parser.print_help()
        sys.exit(2)

    args = parser.parse_args()

    if args.refs:
        args.refs = check_output(git_cmd + ['rev-parse', '--symbolic-full-name'] + args.refs).splitlines()
    else:
        args.refs = get_all_refs(lambda r, t, tt: t == 'commit' or tt == 'commit')

    args.refs = list(filter(lambda r: not r.endswith('/HEAD'), args.refs))
    args.revisions = check_output(git_cmd + ['rev-parse'] + ['%s^{}' % i for i in args.revisions]).splitlines()
    return args


def check_output(cmd, input=None):
    return subprocess.check_output(cmd, universal_newlines=True, input=input)


def make_shallow(shallow_file, revisions, refs):
    """Remove the history of the specified revisions."""
    for rev in follow_history_intersections(revisions, refs):
        print("Processing %s" % rev)
        with open(shallow_file, 'a') as f:
            f.write(rev + '\n')


def get_all_refs(ref_filter=None):
    """Return all the existing refs in this repository, optionally filtering the refs."""
    ref_output = check_output(git_cmd + ['for-each-ref', '--format=%(refname)\t%(objecttype)\t%(*objecttype)'])
    ref_split = [tuple(iter_extend(l.rsplit('\t'), 3)) for l in ref_output.splitlines()]
    if ref_filter:
        ref_split = (e for e in ref_split if ref_filter(*e))
    refs = [r[0] for r in ref_split]
    return refs


def iter_extend(iterable, length, obj=None):
    """Ensure that iterable is the specified length by extending with obj."""
    return itertools.islice(itertools.chain(iterable, itertools.repeat(obj)), length)


def filter_refs(refs):
    """Remove all but the specified refs from the git repository."""
    all_refs = get_all_refs()
    to_remove = set(all_refs) - set(refs)
    if to_remove:
        check_output(['xargs', '-0', '-n', '1'] + git_cmd + ['update-ref', '-d', '--no-deref'],
                     input=''.join(l + '\0' for l in to_remove))


def follow_history_intersections(revisions, refs):
    """Determine all the points where the history of the specified revisions intersects the specified refs."""
    queue = collections.deque(revisions)
    seen = set()

    for rev in iter_except(queue.popleft, IndexError):
        if rev in seen:
            continue

        parents = check_output(git_cmd + ['rev-parse', '%s^@' % rev]).splitlines()

        yield rev
        seen.add(rev)

        if not parents:
            continue

        check_refs = check_output(git_cmd + ['merge-base', '--independent'] + sorted(refs)).splitlines()
        for parent in parents:
            for ref in check_refs:
                print("Checking %s vs %s" % (parent, ref))
                try:
                    merge_base = check_output(git_cmd + ['merge-base', parent, ref]).rstrip()
                except subprocess.CalledProcessError:
                    continue
                else:
                    queue.append(merge_base)


def iter_except(func, exception, start=None):
    """Yield a function repeatedly until it raises an exception."""
    try:
        if start is not None:
            yield start()
        while True:
            yield func()
    except exception:
        pass


def shrink_repo(git_dir):
    """Shrink the newly shallow repository, removing the unreachable objects."""
    subprocess.check_call(git_cmd + ['reflog', 'expire', '--expire-unreachable=now', '--all'])
    subprocess.check_call(git_cmd + ['repack', '-ad'])
    try:
        os.unlink(os.path.join(git_dir, 'objects', 'info', 'alternates'))
    except OSError as exc:
        if exc.errno != errno.ENOENT:
            raise
    subprocess.check_call(git_cmd + ['prune', '--expire', 'now'])


if __name__ == '__main__':
    main()
