#!/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]);
