"""generate_models_from_schema.py — schema model generation

Mirrors schemas/generated/*.schema.json into src/quant_engine/models/generated
as lightweight Python model descriptors.
"""
from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any


ROOT = Path(__file__).resolve().parents[2]
SCHEMA_DIR = ROOT / "schemas" / "generated"
OUT_DIR = ROOT / "src" / "quant_engine" / "models" / "generated"


def load_json(path: Path) -> dict[str, Any]:
    try:
        obj = json.loads(path.read_text(encoding="utf-8"))
    except Exception:
        return {}
    return obj if isinstance(obj, dict) else {}


def to_module_name(path: Path) -> str:
    return path.stem.replace(".", "_").lower()


def render_module(schema_path: Path, schema: dict[str, Any]) -> str:
    title = str(schema.get("title") or schema_path.stem)
    schema_id = str(schema.get("$id") or f"schema://{title}")
    props = schema.get("properties") if isinstance(schema.get("properties"), dict) else {}
    required = schema.get("required") if isinstance(schema.get("required"), list) else []
    prop_names = list(props.keys())
    return (
        '"""Auto-generated schema model descriptor."""\n'
        "from __future__ import annotations\n\n"
        "from dataclasses import dataclass\n"
        "import json\n"
        "from pathlib import Path\n"
        "from typing import Any\n\n"
        f"SCHEMA_TITLE = {title!r}\n"
        f"SCHEMA_ID = {schema_id!r}\n"
        f"SCHEMA_PATH = {str(schema_path.relative_to(ROOT)).replace('\\', '/')!r}\n"
        f"SCHEMA_PROPERTIES = {prop_names!r}\n"
        f"SCHEMA_REQUIRED = {required!r}\n\n"
        "@dataclass(frozen=True)\n"
        "class SchemaModel:\n"
        "    title: str\n"
        "    schema_id: str\n"
        "    path: str\n"
        "    properties: list[str]\n"
        "    required: list[str]\n\n"
        "def load_schema() -> dict[str, Any]:\n"
        "    return json.loads(Path(__file__).with_suffix('.schema.json').read_text(encoding='utf-8'))\n\n"
        "def describe() -> SchemaModel:\n"
        "    return SchemaModel(\n"
        "        title=SCHEMA_TITLE,\n"
        "        schema_id=SCHEMA_ID,\n"
        "        path=SCHEMA_PATH,\n"
        "        properties=list(SCHEMA_PROPERTIES),\n"
        "        required=list(SCHEMA_REQUIRED),\n"
        "    )\n"
    )


def write_text(path: Path, text: str) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(text, encoding="utf-8")


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--schemas", default=str(SCHEMA_DIR))
    parser.add_argument("--out", default=str(OUT_DIR))
    parser.add_argument("--report", default=str(ROOT / "Temp" / "schema_model_generation_v1.json"))
    args = parser.parse_args()

    schema_dir = Path(args.schemas)
    out_dir = Path(args.out)

    schema_files = sorted(schema_dir.glob("*.schema.json"))
    modules = []
    for schema_file in schema_files:
        schema = load_json(schema_file)
        module_name = to_module_name(schema_file)
        modules.append(module_name)
        write_text(out_dir / f"{module_name}.py", render_module(schema_file, schema))
        write_text(out_dir / f"{module_name}.schema.json", json.dumps(schema, ensure_ascii=False, indent=2) + "\n")

    write_text(out_dir / "__init__.py", '"""Auto-generated schema model package."""\n')
    write_text(
        out_dir.parent / "__init__.py",
        '"""Auto-generated quant_engine.models package."""\n',
    )
    write_text(
        out_dir.parent.parent / "__init__.py",
        '"""Canonical quant_engine package."""\n',
    )
    write_text(
        out_dir.parent.parent.parent / "__init__.py",
        '"""Canonical src package."""\n',
    )

    report = {
        "status": "OK",
        "schema_count": len(schema_files),
        "generated_module_count": len(modules),
        "package_root": "src/quant_engine/models/generated",
        "report_path": str(Path(args.report).relative_to(ROOT)),
    }
    write_text(Path(args.report), json.dumps(report, ensure_ascii=False, indent=2) + "\n")
    print(json.dumps(report, ensure_ascii=False, indent=2))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
