#!/usr/bin/env python3

import argparse
import os
import sys
from typing import Optional


def print_array(name: str, values: list[str]) -> None:
    if len(values) == 0:
        return
    list = ", ".join(values)
    print(f"    .{name} = ((const char*[]){{ {list}, NULL }}),")

def parse_line(line: str) -> tuple[str, str]:
    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 parse_modinfo(name: str, lines: list[str], enabled: set[str]) -> Optional[dict]:
    """Parse a modinfo file and return module metadata, or None if disabled."""
    arch = ""
    objs = []
    deps = []
    opts = []
    for line in lines:
        if "MODINFO_START" in line:
            (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:
                    return None
            else:
                print("unknown:", kind)
                exit(1)

    return {
        'name': name,
        'arch': arch,
        'objs': objs,
        'deps': deps,
        'opts': opts,
        'dep_names': {dep.strip('" ') for dep in deps}
    }

def generate(modinfo: str, mod: Optional[dict],
             skip_reason: Optional[str]) -> None:
    """Generate C code for a module."""
    print(f"    /* {modinfo} */")
    if mod is None:
        if skip_reason == "missing_deps":
            print("    /* module has missing dependencies. */")
        else:
            print("    /* module isn't enabled in Kconfig. */")
        print("/* },{ */")
        return

    print(f'    .name = "{mod["name"]}",')
    if mod['arch'] != "":
        print(f"    .arch = {mod['arch']},")
    print_array("objs", mod['objs'])
    print_array("deps", mod['deps'])
    print_array("opts", mod['opts'])
    print("},{")

def print_pre() -> None:
    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() -> None:
    print("    /* end of list */")
    print("}};")

def main() -> None:
    parser = argparse.ArgumentParser(
        description='Generate C code for QEMU module info'
    )
    parser.add_argument('--devices',
                        help='path to config-device.mak')
    parser.add_argument('--skip-missing-deps', action='store_true',
                        help='warn if a dependency is missing and continue')
    parser.add_argument('modinfo', nargs='+',
                        help='modinfo files to process')
    args = parser.parse_args()

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

    # all_modules: modinfo path -> (basename, parsed module or None, skip_reason)
    all_modules = {}
    for modinfo in args.modinfo:
        with open(modinfo) as f:
            lines = f.readlines()
        (basename, _) = os.path.splitext(modinfo)
        mod = parse_modinfo(basename, lines, enabled)
        skip_reason = "kconfig" if mod is None else None
        all_modules[modinfo] = (basename, mod, skip_reason)

    # Collect all available module names
    available = {basename for basename, mod, _ in all_modules.values()
                 if mod is not None}

    # Collect all dependencies
    all_deps = set()
    for basename, mod, _ in all_modules.values():
        if mod is not None:
            all_deps.update(mod['dep_names'])

    # Check for missing dependencies
    missing = all_deps.difference(available)
    for dep in missing:
        print(f"Dependency {dep} cannot be satisfied", file=sys.stderr)

    if missing and not args.skip_missing_deps:
        exit(1)

    # When skipping missing deps, iteratively remove modules with
    # unsatisfiable dependencies
    if args.skip_missing_deps and missing:
        changed = True
        while changed:
            changed = False
            for modinfo, (basename, mod, skip_reason) in list(all_modules.items()):
                if mod is None:
                    continue
                if not mod['dep_names'].issubset(available):
                    available.discard(basename)
                    all_modules[modinfo] = (basename, None, "missing_deps")
                    changed = True

    # generate output
    print_pre()
    for modinfo in args.modinfo:
        (basename, mod, skip_reason) = all_modules[modinfo]
        generate(modinfo, mod, skip_reason)
    print_post()

if __name__ == "__main__":
    main()
