/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */

"use strict";

// gcc appends this to mangled function names for "not in charge"
// constructors/destructors.
var internalMarker = " *INTERNAL* ";

if (! Set.prototype.hasOwnProperty("update")) {
    Object.defineProperty(Set.prototype, "update", {
        value: function (collection) {
            for (let elt of collection)
                this.add(elt);
        }
    });
}

function assert(x, msg)
{
    if (x)
        return;
    debugger;
    if (msg)
        throw "assertion failed: " + msg + "\n" + (Error().stack);
    else
        throw "assertion failed: " + (Error().stack);
}

function defined(x) {
    return x !== undefined;
}

function xprint(x, padding)
{
    if (!padding)
        padding = "";
    if (x instanceof Array) {
        print(padding + "[");
        for (var elem of x)
            xprint(elem, padding + " ");
        print(padding + "]");
    } else if (x instanceof Object) {
        print(padding + "{");
        for (var prop in x) {
            print(padding + " " + prop + ":");
            xprint(x[prop], padding + "  ");
        }
        print(padding + "}");
    } else {
        print(padding + x);
    }
}

function sameBlockId(id0, id1)
{
    if (id0.Kind != id1.Kind)
        return false;
    if (!sameVariable(id0.Variable, id1.Variable))
        return false;
    if (id0.Kind == "Loop" && id0.Loop != id1.Loop)
        return false;
    return true;
}

function sameVariable(var0, var1)
{
    assert("Name" in var0 || var0.Kind == "This" || var0.Kind == "Return");
    assert("Name" in var1 || var1.Kind == "This" || var1.Kind == "Return");
    if ("Name" in var0)
        return "Name" in var1 && var0.Name[0] == var1.Name[0];
    return var0.Kind == var1.Kind;
}

function blockIdentifier(body)
{
    if (body.BlockId.Kind == "Loop")
        return body.BlockId.Loop;
    assert(body.BlockId.Kind == "Function", "body.Kind should be Function, not " + body.BlockId.Kind);
    return body.BlockId.Variable.Name[0];
}

function collectBodyEdges(body)
{
    body.predecessors = [];
    body.successors = [];
    if (!("PEdge" in body))
        return;

    for (var edge of body.PEdge) {
        var [ source, target ] = edge.Index;
        if (!(target in body.predecessors))
            body.predecessors[target] = [];
        body.predecessors[target].push(edge);
        if (!(source in body.successors))
            body.successors[source] = [];
        body.successors[source].push(edge);
    }
}

function getPredecessors(body)
{
    try {
        if (!('predecessors' in body))
            collectBodyEdges(body);
    } catch (e) {
        debugger;
        printErr("body is " + body);
    }
    return body.predecessors;
}

function getSuccessors(body)
{
    if (!('successors' in body))
        collectBodyEdges(body);
    return body.successors;
}

// Split apart a function from sixgill into its mangled and unmangled name. If
// no mangled name was given, use the unmangled name as its mangled name
function splitFunction(func)
{
    var split = func.indexOf("$");
    if (split != -1)
        return [ func.substr(0, split), func.substr(split+1) ];
    split = func.indexOf("|");
    if (split != -1)
        return [ func.substr(0, split), func.substr(split+1) ];
    return [ func, func ];
}

function mangled(fullname)
{
    var [ mangled, unmangled ] = splitFunction(fullname);
    return mangled;
}

function readable(fullname)
{
    var [ mangled, unmangled ] = splitFunction(fullname);
    return unmangled;
}

function xdbLibrary()
{
    var lib = ctypes.open(os.getenv('XDB'));
    var api = {
        open: lib.declare("xdb_open", ctypes.default_abi, ctypes.void_t, ctypes.char.ptr),
        min_data_stream: lib.declare("xdb_min_data_stream", ctypes.default_abi, ctypes.int),
        max_data_stream: lib.declare("xdb_max_data_stream", ctypes.default_abi, ctypes.int),
        read_key: lib.declare("xdb_read_key", ctypes.default_abi, ctypes.char.ptr, ctypes.int),
        read_entry: lib.declare("xdb_read_entry", ctypes.default_abi, ctypes.char.ptr, ctypes.char.ptr),
        free_string: lib.declare("xdb_free", ctypes.default_abi, ctypes.void_t, ctypes.char.ptr)
    };
    try {
        api.lookup_key = lib.declare("xdb_lookup_key", ctypes.default_abi, ctypes.int, ctypes.char.ptr);
    } catch (e) {
        // lookup_key is for development use only and is not strictly necessary.
    }
    return api;
}

function cLibrary()
{
    var lib;
    try {
        lib = ctypes.open("libc.so.6");
    } catch(e) {
        lib = ctypes.open("libc.so");
    }

    return {
        fopen: lib.declare("fopen", ctypes.default_abi, ctypes.void_t.ptr, ctypes.char.ptr, ctypes.char.ptr),
        getline: lib.declare("getline", ctypes.default_abi, ctypes.ssize_t, ctypes.char.ptr.ptr, ctypes.size_t.ptr, ctypes.void_t.ptr),
        fclose: lib.declare("fclose", ctypes.default_abi, ctypes.int, ctypes.void_t.ptr),
        free: lib.declare("free", ctypes.default_abi, ctypes.void_t, ctypes.void_t.ptr),
    };
}

function* readFileLines_gen(filename)
{
    var libc = cLibrary();
    var linebuf = ctypes.char.ptr();
    var bufsize = ctypes.size_t(0);
    var fp = libc.fopen(filename, "r");
    if (fp.isNull())
        throw "Unable to open '" + filename + "'"

    while (libc.getline(linebuf.address(), bufsize.address(), fp) > 0)
        yield linebuf.readString();
    libc.fclose(fp);
    libc.free(ctypes.void_t.ptr(linebuf));
}

function addToKeyedList(collection, key, entry)
{
    if (!(key in collection))
        collection[key] = [];
    collection[key].push(entry);
}

function loadTypeInfo(filename)
{
    var info = {};
    for (var line of readFileLines_gen(filename)) {
        line = line.replace(/\n/, "");
        let [property, name] = line.split("$$");
        addToKeyedList(info, property, name);
    }
    return info;
}
