#!/usr/bin/env python3
"""Capture the exact error messages Python YAML parsers emit for common
hand-written YAML mistakes (invalid documents), including whether the
parser reports a line/column.

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-syntax-errors
  python3 -m venv venv && ./venv/bin/pip install pyyaml ruamel.yaml
  ./venv/bin/python measure.py    # prints JSON, writes results-python.json
"""
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(value):
    if value is None:
        return {"outcome": "parsed", "type": "null", "repr": "null"}
    type_name = "array" if isinstance(value, list) else type(value).__name__
    return {
        "outcome": "parsed",
        "type": type_name,
        "repr": json.dumps(value, default=str)[:200],
    }


def mark_of(exc):
    mark = getattr(exc, "problem_mark", None) or getattr(exc, "context_mark", None)
    if mark is None:
        return {"line": None, "column": None}
    return {"line": mark.line + 1, "column": mark.column + 1}


def run(label, parse):
    out = {}
    for case in CASES:
        try:
            out[case["id"]] = describe_value(parse(case["yaml"]))
        except Exception as exc:  # noqa: BLE001 - we want the real error text
            pos = mark_of(exc)
            out[case["id"]] = {
                "outcome": "error",
                "errorName": type(exc).__name__,
                "message": " ".join(str(exc).split())[:300],
                "line": pos["line"],
                "column": pos["column"],
            }
    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__} YAML(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, ensure_ascii=False) + "\n")
    json.dump(payload, sys.stdout, indent=2, ensure_ascii=False)
    print()


if __name__ == "__main__":
    main()
