#!/usr/bin/env python3
# Copyright 2018 Mellanox Technologies Inc.
# Licensed under BSD (MIT variant) or GPLv2. See COPYING.
# PYTHON_ARGCOMPLETE_OK
"""This script takes a commitish from a kernel tree and synchronizes the RDMA
headers we use with that tree.

During development, before commits are accepted to the official kernel git
tree, the --not-final option should be used. Once finalized the commit should
be revised using --amend, eg using the exec feature of 'git rebase'"""
import argparse
import subprocess
import tempfile
import os
import contextlib
import textwrap
import email.utils
import collections

def git_call(args):
    """Run git and display the output to the terminal"""
    return subprocess.check_call(['git',] + args);

def git_output(args,mode=None,input=None):
    """Run git and return the output"""
    o = subprocess.check_output(['git',] + args,input=input);
    if mode == "raw":
        return o;
    return o.strip();

@contextlib.contextmanager
def in_directory(dir):
    """Context manager that chdirs into a directory and restores the original
    directory when closed."""
    cdir = os.getcwd();
    old_env = {};
    try:
        # git rebase invokes its exec with a bunch of git variables set that
        # prevent us from invoking git in another tree, blow them away.
        for k in list(os.environ.keys()):
            if k.startswith("GIT"):
                old_env[k] = os.environ[k];
                del os.environ[k];

        os.chdir(dir);
        yield True;
    finally:
        os.chdir(cdir);
        os.environ.update(old_env);

def copy_objects(args):
    """Copy the uapi header objects from the kernel repo at the commit indicated
    into our repo. This is done by having git copy the tree object and blobs from the
    kernel tree into this tree and then revising our index. This is a simple way
    to ensure they match exactly."""
    with in_directory(args.KERNEL_GIT):
        if args.not_final:
            fmt = "--format=?? (\"%s\")";
        else:
            fmt = "--format=%h (\"%s\")";

        kernel_desc = git_output(["log",
                                  "--abbrev=12","-1",
                                  fmt,
                                  args.COMMIT]);
        ntree = git_output(["rev-parse",
                            "%s:include/uapi/rdma"%(args.COMMIT)]);
        pack = git_output(["pack-objects",
                           "-q","--revs","--stdout"],
                          mode="raw",
                          input=ntree);
    git_output(["unpack-objects","-q"],input=pack);
    return (ntree,kernel_desc);

def update_cmake(args,ntree):
    """Create a new CMakeLists.txt that lists all of the kernel headers
    for installation."""
    # We need to expand to a publish_internal_headers for each directory
    fns = git_output(["ls-tree","--name-only","--full-tree","-r",ntree]).splitlines();
    groups = collections.defaultdict(list);
    for I in fns:
        d,p = os.path.split(os.path.join("rdma",I.decode()));
        groups[d].append(p);

    data = subprocess.check_output(['git',"cat-file","blob",
                                    ":kernel-headers/CMakeLists.txt"]);
    data = data.decode();

    # Build a new CMakeLists.txt in a temporary file
    with tempfile.NamedTemporaryFile("wt") as F:
        # Emit the headers lists
        for I,vals in sorted(groups.items()):
            F.write("publish_internal_headers(%s\n"%(I));
            for J in sorted(vals):
                F.write("  %s\n"%(os.path.join(I,J)));
            F.write("  )\n");
            F.write("\n");

        # Throw away the old header lists
        cur = iter(data.splitlines());
        for ln in cur:
            if not ln:
                continue;
            if ln.startswith("publish_internal_headers(rdma"):
                while not next(cur).startswith("  )"):
                    pass;
                continue;
            F.write(ln + '\n');
            break;

        # and copy the remaining lines
        for ln in cur:
            F.write(ln + '\n');

        F.flush();
        blob = git_output(["hash-object","-w",F.name]);

    git_call(["update-index","--cacheinfo",
              b"0644,%s,kernel-headers/CMakeLists.txt"%(blob)]);

def make_commit(args,ntree,kernel_desc):
    """Make the rdma-core commit that syncs the kernel header directory."""
    head_id = git_output(["rev-parse","HEAD"]);
    old_tree_id = git_output(["rev-parse",b"%s^{tree}"%(head_id)]);

    if args.amend:
        subject = git_output(["log","-1","--format=%s"]).decode();
        if subject != "Update kernel headers":
            raise ValueError("In amend mode, but current HEAD does not seem to be a kernel update with subject %r"%(
                subject));
        parent = git_output(["rev-parse",head_id + b"^"]);
    else:
        parent = head_id;

    emaila = email.utils.formataddr((git_output(["config","user.name"]).decode(),
                                     git_output(["config","user.email"]).decode()));

    # Build a new tree object that replaces the kernel headers directory
    with tempfile.NamedTemporaryFile() as F:
        os.environ["GIT_INDEX_FILE"] = F.name;
        git_call(["read-tree",head_id]);
        git_call(["rm","-r","--quiet","--cached",
                    "kernel-headers/rdma"]);
        git_call(["read-tree","--prefix=kernel-headers/rdma",ntree]);
        update_cmake(args,ntree);
        all_tree = git_output(["write-tree"]);
        del os.environ["GIT_INDEX_FILE"];

    if not args.amend and old_tree_id == all_tree:
        raise ValueError("Commit is empty, aborting");

    # And now create the commit
    msg="Update kernel headers\n\n";
    p = textwrap.fill("To commit %s."%(kernel_desc.decode()),
                      width=74)
    msg = msg + p;
    msg = msg + "\n\nSigned-off-by: %s\n"%(emaila);

    commit = git_output(["commit-tree",all_tree,"-p",parent,
                         "-F","-"],
                        input=msg.encode());
    return commit,head_id;

parser = argparse.ArgumentParser(description='Update kernel headers from the kernel tree')
parser.add_argument("--amend",
                    action="store_true",
                    default=False,
                    help="Replace the top commit with the the kernel header commit");
parser.add_argument("--not-final",
                    action="store_true",
                    default=False,
                    help="Use if the git commit given is not part of the official kernel git tree. This option should be used during development.");
parser.add_argument("KERNEL_GIT",
                    action="store",
                    help="Kernel git directory");
parser.add_argument("COMMIT",
                    action="store",
                    help="Kernel commitish to synchronize headers with");

try:
    import argcomplete;
    argcomplete.autocomplete(parser);
except ImportError:
    pass;

args = parser.parse_args();

ntree,kernel_desc = copy_objects(args);
commit,head_id = make_commit(args,ntree,kernel_desc);

# Finalize
if args.amend:
    print("Commit amended");
    git_call(["--no-pager","diff","--stat",head_id,commit]);
    git_call(["reset","--merge",commit]);
else:
    git_call(["merge","--ff","--ff-only",commit]);
