#!/usr/bin/env python3
"""Generate static enum declarations for the dynamically loaded input codes."""

from __future__ import annotations

import argparse
import sys
from pathlib import Path
from typing import TYPE_CHECKING

from scc.cheader import defines

if TYPE_CHECKING:
	from collections.abc import Callable

REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPOSITORY_ROOT))


def enum_block(name: str, values: dict[str, int], include: Callable[[str], bool]) -> list[str]:
	"""Return one IntEnum declaration for matching C defines."""
	lines = [f"class {name}(IntEnum):"]
	lines.extend(f"\t{key} = {value}" for key, value in values.items() if include(key))
	if len(lines) == 1:
		lines.append("\tpass")
	return lines


def generate(include_root: Path, header: str) -> str:
	"""Generate the complete stub text from a Linux input header."""
	values = dict(defines(str(include_root), header))
	blocks = [
		enum_block("Keys", values, lambda key: key.startswith(("KEY_", "BTN_"))),
		enum_block("KeysOnly", values, lambda key: key.startswith("KEY_")),
		enum_block("Axes", values, lambda key: key.startswith("ABS_")),
		enum_block("Rels", values, lambda key: key.startswith("REL_")),
	]
	lines = [
		'"""Generated by scripts/generate-uinput-stubs.py; do not edit."""',
		"",
		"from enum import IntEnum",
		"",
	]
	for block in blocks:
		lines.extend(block)
		lines.extend(("", ""))
	return "\n".join(lines).rstrip() + "\n"


def main() -> None:
	"""Parse arguments and write the generated stub."""
	parser = argparse.ArgumentParser()
	parser.add_argument("--include-root", type=Path, default=Path("/usr/include"))
	parser.add_argument("--header", default="linux/input-event-codes.h")
	parser.add_argument("--output", type=Path, default=REPOSITORY_ROOT / "scc/_uinput_codes.pyi")
	args = parser.parse_args()

	args.output.write_text(generate(args.include_root, args.header), encoding="utf-8")


if __name__ == "__main__":
	main()
