#!/usr/bin/env python3
# Copyright 2015-2017 Obsidian Research Corp.
# Licensed under BSD (MIT variant) or GPLv2. See COPYING.
import argparse
import subprocess
import os
import collections
import re
import itertools

headers = {
    "bits/sysmacros.h",
    "endian.h",
    "netinet/in.h",
    "pthread.h",
    "stdatomic.h",
    "stdlib.h",
    "sys/socket.h",
    };

def norm_header(fn):
    for I in headers:
        flat = I.replace("/","-");
        if fn.endswith(flat):
            return I;
        if fn.endswith(flat + ".diff"):
            return I;
    return None;

def find_system_header(args,hdr):
    """/usr/include is not always where the include files are, particularly if we
    are running full multi-arch as the azure_pipeline container does. Get gcc
    to tell us where /usr/include is"""
    if "incpath" not in args:
        cpp = subprocess.check_output([args.cc, "-print-prog-name=cpp"],universal_newlines=True).strip()
        data = subprocess.check_output([cpp, "-v"],universal_newlines=True,stdin=subprocess.DEVNULL,
                                       stderr=subprocess.STDOUT)
        args.incpath = [];
        for incdir in re.finditer(r"^ (/\S+)$", data, re.MULTILINE):
            incdir = incdir.group(1)
            if "fixed" in incdir:
                continue;
            args.incpath.append(incdir)

    for incdir in args.incpath:
        fn = os.path.join(incdir,hdr)
        if os.path.exists(fn):
            return fn
    return None;

def get_buildlib_patches(dfn):
    """Within the buildlib directory we store patches for the glibc headers. Each
    patch is in a numbered sub directory that indicates the order to try, the
    number should match the glibc version used to make the diff."""
    ver_hdrs = [];
    all_hdrs = []
    for d,_,files in os.walk(dfn):
        for I in files:
            if d != dfn:
                bn = int(os.path.basename(d));
            else:
                bn = 0;

            if bn == 0:
                all_hdrs.append(os.path.join(d,I));
            else:
                ver_hdrs.append((bn,os.path.join(d,I)));
    ver_hdrs.sort(reverse=True);

    def add_to_dict(d,lst):
        for I in lst:
            nh = norm_header(I)
            if nh is None:
                continue;
            assert nh not in d
            d[nh] = (I, find_system_header(args,nh))

    ret = []
    for k,g in itertools.groupby(ver_hdrs,key=lambda x:x[0]):
        dd = {}
        ret.append(dd)
        add_to_dict(dd,(I for _,I in g))
        add_to_dict(dd,all_hdrs)
    return ret;

def is_patch(fn):
    with open(fn) as F:
        return F.read(10).startswith("-- /");

def apply_patch(src,patch,dest):
    """Patch a single system header. The output goes into our include search path
    and takes precedence over the system version."""
    if src is None:
        return False

    dfn = os.path.dirname(dest);
    if not os.path.isdir(dfn):
        os.makedirs(dfn);

    if not patch.endswith(".diff"):
        if not os.path.exists(dest):
            os.symlink(patch,dest);
        return True;

    try:
        if os.path.exists(dest + ".rej"):
            os.unlink(dest + ".rej");

        subprocess.check_output(["patch","-f","--follow-symlinks","-V","never","-i",patch,"-o",dest,src]);

        if os.path.exists(dest + ".rej"):
            print("Patch from %r failed"%(patch));
            return False;
    except subprocess.CalledProcessError:
        print("Patch from %r failed"%(patch));
        return False;
    return True;

def replace_headers(suite):
    # Local system does not have the reference system header, this suite is
    # not supported
    for fn,pfn in suite.items():
        if pfn[1] is None:
            return False;

    for fn,pfn in suite.items():
        if not apply_patch(pfn[1],pfn[0],os.path.join(args.INCLUDE,fn)):
            break;
    else:
        return True;

    for fn,_ in suite.items():
        try:
            os.unlink(os.path.join(args.INCLUDE,fn))
        except OSError:
            continue;
    return False;

def save(fn,outdir):
    """Diff the header file in our include directory against the system header and
    store the diff into buildlib. This makes it fairly easy to maintain the
    replacement headers."""
    if os.path.islink(os.path.join(args.INCLUDE,fn)):
        return;

    flatfn = fn.replace("/","-") + ".diff";
    flatfn = os.path.join(outdir,flatfn);

    with open(flatfn,"wt") as F:
        try:
            subprocess.check_call(["diff","-u",
                                   find_system_header(args,fn),
                                   os.path.join(args.INCLUDE,fn)],
                                  stdout=F);
        except subprocess.CalledProcessError as ex:
            if ex.returncode == 1:
                return;
            raise;

parser = argparse.ArgumentParser(description='Produce sparse shim header files')
parser.add_argument("--out",dest="INCLUDE",required=True,
                    help="Directory to write header files to");
parser.add_argument("--src",dest="SRC",required=True,
                    help="Top of the source tree");
parser.add_argument("--cc",default="gcc",
                    help="System compiler to use to locate the default system headers");
parser.add_argument("--save",action="store_true",default=False,
                    help="Save mode will write the current content of the headers to buildlib as a diff.");
args = parser.parse_args();

if args.save:
    # Get the glibc version string
    ver = subprocess.check_output(["ldd","--version"]).decode()
    ver = ver.splitlines()[0].split(' ')[-1];
    ver = ver.partition(".")[-1];
    outdir = os.path.join(args.SRC,"buildlib","sparse-include",ver);
    if not os.path.isdir(outdir):
        os.makedirs(outdir);

    for I in headers:
        save(I,outdir);
else:
    failed = False;
    suites = get_buildlib_patches(os.path.join(args.SRC,"buildlib","sparse-include"));
    for I in suites:
        if replace_headers(I):
            break;
    else:
        raise ValueError("Patch applications failed");
