#! /usr/bin/env python
import sys, re
from subprocess import Popen, PIPE

def enum_prefix(has_result):
    if has_result == "true":
        return "RPCM_"
    else:
        return "RPNM_"

def add_enums(template_name, hashtable_name, header_name):
    headline = "/* generated by make_jsonrpc_methods.py */\n\n"
    gperf_program = "gperf"
    hashtable = open(hashtable_name, "w")
    hashtable.write(headline)
    hashtable.flush()
    gperf = Popen([gperf_program, "-L", "C++"], stdin=PIPE, stdout=hashtable)
    enumlist = []
    section = 0
    in_comment = False
    for line in open(template_name):
        if in_comment:
            if "*/" not in line:
                continue
            line = re.sub(r"^.*\*/", "", line).strip()
        elif line.startswith("%%"):
            section += 1
            gperf.stdin.write(line.encode("utf-8"));
            continue
        if section != 1:
            gperf.stdin.write(line.encode("utf-8"));
            continue
        if "//" in line:
            line = re.sub("//.*", "", line)
        if "/*" in line:
            line = re.sub(r"/\*.*\*/", "", line)
        if "/*" in line:
            line = re.sub(r"/\*.*", "", line)
            in_comment = True
        line = line.strip()
        if line:
            name, has_result = line.split(",")
            name = name.strip()
            has_result = has_result.strip()
            enum = enum_prefix(has_result) + name.strip('"')
            enumlist.append((enum, name, has_result))
            gperf.stdin.write(("%s, %s\n" % (name, enum)).encode("utf-8"))
    gperf.stdin.close();
    struct = "jsonrpc_method_def"
    header = open(header_name, "w")
    header.write(headline)
    headtag = "SRC_HEADERS_JSONRPC_METHODS_H_"
    header.write("#pragma once\n\n#ifndef %s\n#define %s\n\n" % (headtag, headtag))
    header.write("enum jsonrpc_method {\n")
    for enum, name, has_result in enumlist:
        header.write("\t%s,\n" % enum);
    header.write("};\n\n")
    header.write("struct %s {\n\tconst char *name;\n\tbool has_result;\n};\n\n" % struct)
    header.write("extern const %s jsonrpc_method_list[];\n" % struct);
    header.write("\n#endif  // %s\n" % headtag)
    header.close()
    ret = gperf.wait()
    if ret != 0:
        raise SystemExit(ret)
    hashtable.write("\nconst %s jsonrpc_method_list[] = {\n" % struct)
    for enum, name, has_result in enumlist:
        hashtable.write('\t{ %s, %s },\n' % (name, has_result));
    hashtable.write("};\n");

if __name__ == "__main__":
    args = sys.argv[1:]
    if not args:
        args = "jsonrpc_methods.gperf_tmpl", "jsonrpc_methods-generated.cc", "jsonrpc_methods-generated.h"
    add_enums(*args)
