#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys

def print_array(name, values):
    if len(values) == 0:
        return
    list = ", ".join(values)
    print("    .%s = ((const char*[]){ %s, NULL })," % (name, list))

def parse_line(line):
    kind = ""
    data = ""
    get_kind = False
    get_data = False
    for item in line.split():
        if item == "MODINFO_START":
            get_kind = True
            continue
        if item.startswith("MODINFO_END"):
            get_data = False
            continue
        if get_kind:
            kind = item
            get_kind = False
            get_data = True
            continue
        if get_data:
            data += " " + item
            continue
    return (kind, data)

def generate(name, lines, enabled):
    arch = ""
    objs = []
    deps = []
    opts = []
    for line in lines:
        if line.find("MODINFO_START") != -1:
            (kind, data) = parse_line(line)
            if kind == 'obj':
                objs.append(data)
            elif kind == 'dep':
                deps.append(data)
            elif kind == 'opts':
                opts.append(data)
            elif kind == 'arch':
                arch = data;
            elif kind == 'kconfig':
                # don't add a module which dependency is not enabled
                # in kconfig
                if data.strip() not in enabled:
                    print("    /* module {} isn't enabled in Kconfig. */"
                          .format(data.strip()))
                    print("/* },{ */")
                    return None
            else:
                print("unknown:", kind)
                exit(1)

    print("    .name = \"%s\"," % name)
    if arch != "":
        print("    .arch = %s," % arch)
    print_array("objs", objs)
    print_array("deps", deps)
    print_array("opts", opts)
    print("},{")
    return {dep.strip('" ') for dep in deps}

def print_pre():
    print("/* generated by scripts/modinfo-generate.py */")
    print("#include \"qemu/osdep.h\"")
    print("#include \"qemu/module.h\"")
    print("const QemuModinfo qemu_modinfo[] = {{")

def print_post():
    print("    /* end of list */")
    print("}};")

def main(args):
    if len(args) < 3 or args[0] != '--devices':
        print('Expected: modinfo-generate.py --devices '
              'config-device.mak [modinfo files]', file=sys.stderr)
        exit(1)

    # get all devices enabled in kconfig, from *-config-device.mak
    enabled = set()
    with open(args[1]) as file:
        for line in file.readlines():
            config = line.split('=')
            if config[1].rstrip() == 'y':
                enabled.add(config[0][7:]) # remove CONFIG_

    deps = set()
    modules = set()
    print_pre()
    for modinfo in args[2:]:
        with open(modinfo) as f:
            lines = f.readlines()
        print("    /* %s */" % modinfo)
        (basename, _) = os.path.splitext(modinfo)
        moddeps = generate(basename, lines, enabled)
        if moddeps is not None:
            modules.add(basename)
            deps.update(moddeps)
    print_post()

    error = False
    for dep in deps.difference(modules):
        print("Dependency {} cannot be satisfied".format(dep),
              file=sys.stderr)
        error = True

    if error:
        exit(1)

if __name__ == "__main__":
    main(sys.argv[1:])
