#!/usr/bin/python3
# AP_FLAKE8_CLEAN
"""Generate all standard types and round-trip representative C encodings."""

import argparse
import os
from pathlib import Path
import subprocess
import tempfile

import dronecan


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--compiler", type=Path, default=Path("/usr/bin/dronecan-dsdlc"))
    args = parser.parse_args()
    command = [str(args.compiler)]
    if args.compiler.suffix == ".py":
        command.insert(0, "/usr/bin/python3")
    definitions = Path(dronecan.__file__).parent / "dsdl_specs"
    namespaces = [str(p) for p in sorted(definitions.iterdir()) if p.is_dir() and not p.name.startswith(".")]
    with tempfile.TemporaryDirectory(prefix="dsdlc-test-") as directory:
        work = Path(directory)
        subprocess.run(command + ["--help"], check=True)
        subprocess.run(command + ["-j2", "-O", str(work / "all")] + namespaces, check=True)
        messages = dronecan.dsdl.parse_namespaces(namespaces)
        headers = sum(1 if msg.kind == msg.KIND_MESSAGE else 3 for msg in messages)
        sources = sum(1 if msg.kind == msg.KIND_MESSAGE else 2 for msg in messages)
        assert len(list((work / "all/include").glob("*.h"))) == headers + 1
        assert len(list((work / "all/src").glob("*.c"))) == sources
        print(f"Generated all {len(messages)} types: {headers + 1} headers, {sources} sources", flush=True)
        selected = (
            "uavcan.protocol.NodeStatus",
            "uavcan.protocol.GetNodeInfo",
            "uavcan.protocol.param.GetSet",
            "uavcan.equipment.ahrs.MagneticFieldStrength",
        )
        tests = command + ["-j2", "-O", str(work / "regression output"), "--run-tests"]
        for name in selected:
            tests.extend(["--build", name])
        environment = dict(os.environ, LC_ALL="C.UTF-8")
        subprocess.run(tests + namespaces, check=True, env=environment)
        print("Generated C/Python message and service regression tests passed", flush=True)


if __name__ == "__main__":
    main()
