#!/usr/bin/env python3

def generate(output, config, manifest):
    from os import makedirs
    from glob import iglob
    from pathlib import Path
    from bonnibel.module import Module
    from bonnibel.project import Project

    root = Path(__file__).parent.resolve()
    project = Project(root)

    output = root / output
    manifest = root / manifest

    sources = [
        str(root / "src/**/*.module"),
        str(root / "external/*.module"),
    ]

    modules = {}
    for source in sources:
        for modfile in iglob(source, recursive=True):
            path = Path(modfile).parent

            def module_init(name, **kwargs):
                if not "root" in kwargs:
                    kwargs["root"] = path
                m = Module(name, modfile, **kwargs)
                modules[m.name] = m
                return m

            glo = {
                "module": module_init,
                "source_root": root,
                "build_root": output,
                "module_root": path,
                "config": config,
            }
            code = compile(open(modfile, 'r').read(), modfile, "exec")

            loc = {}
            exec(code, glo, loc)

    Module.update(modules)

    makedirs(output.resolve(), exist_ok=True)
    project.generate(root, output, modules, config, manifest)
    for mod in modules.values():
        mod.generate(output)

if __name__ == "__main__":
    import sys
    from pathlib import Path
    sys.path.insert(0, str(Path(__file__).parent / "scripts"))

    from argparse import ArgumentParser
    from bonnibel import BonnibelError

    p = ArgumentParser(description="Generate jsix build files")
    p.add_argument("--manifest", "-m", metavar="FILE", default="assets/manifests/default.yaml",
            help="File to use as the system manifest")
    p.add_argument("--config", "-c", metavar="NAME", default="debug",
            help="Configuration to build (eg, 'debug' or 'release')")
    p.add_argument("output", metavar="DIR", default="build", nargs='?',
            help="Where to create the build root")

    args = p.parse_args()

    try:
        generate(args.output, args.config, args.manifest)

    except BonnibelError as be:
        import sys
        print(f"Error: {be}", file=sys.stderr)
        sys.exit(1)
