#!/usr/bin/env python3
"""Measure how Python YAML parsers resolve ambiguous YAML 1.1 / 1.2 scalars.

Parsers:
  - PyYAML  yaml.safe_load      -- YAML 1.1 resolution rules
  - ruamel.yaml YAML(typ="safe") -- YAML 1.2 by default

Run:
  cd scripts/benchmarks/yaml-parser-differences
  python3 -m venv venv && ./venv/bin/pip install pyyaml ruamel.yaml
  ./venv/bin/python measure.py    # prints JSON, writes results-python.json
"""
import datetime
import io
import json
import platform
import sys
from pathlib import Path

HERE = Path(__file__).parent
CASES = json.loads((HERE / "cases.json").read_text())


def describe(value):
    if value is None:
        return {"type": "null", "repr": "null"}
    if isinstance(value, bool):
        return {"type": "boolean", "repr": json.dumps(value)}
    if isinstance(value, (int, float)):
        return {"type": "number", "repr": repr(value)}
    if isinstance(value, str):
        return {"type": "string", "repr": json.dumps(value)}
    if isinstance(value, (datetime.date, datetime.datetime)):
        return {"type": type(value).__name__, "repr": value.isoformat()}
    if isinstance(value, dict):
        return {"type": "object", "repr": json.dumps({str(k): repr(v) for k, v in value.items()})}
    return {"type": type(value).__name__, "repr": repr(value)}


def run(label, parse):
    out = {}
    for case in CASES:
        try:
            doc = parse(case["yaml"])
            value = doc["value"] if isinstance(doc, dict) and "value" in doc else doc
            out[case["id"]] = describe(value)
        except Exception as exc:  # noqa: BLE001 - record parser errors verbatim
            out[case["id"]] = {"type": "error", "repr": str(exc).split("\n")[0][:120]}
    return {"parser": label, "results": out}


def main():
    import yaml as pyyaml
    from ruamel.yaml import YAML

    ruamel_safe = YAML(typ="safe")

    def ruamel_parse(text):
        return ruamel_safe.load(io.StringIO(text))

    import ruamel.yaml as ruamel_pkg

    results = [
        run(f"PyYAML {pyyaml.__version__} safe_load", pyyaml.safe_load),
        run(f"ruamel.yaml {ruamel_pkg.__version__} typ=safe", ruamel_parse),
    ]
    payload = {
        "generatedBy": "measure.py",
        "python": platform.python_version(),
        "results": results,
    }
    (HERE / "results-python.json").write_text(json.dumps(payload, indent=2) + "\n")
    json.dump(payload, sys.stdout, indent=2)
    print()


if __name__ == "__main__":
    main()
