"""Validate benchmark items: JSON schema, script sanity, duplicates.

Usage: python -m aixc_eval.validate data/samples/items.jsonl [--strict]
"""
import argparse, json, sys, unicodedata
from pathlib import Path

try:
    import jsonschema
except ImportError:  # keep the validator usable without the dependency
    jsonschema = None

ARABIC_BLOCKS = [(0x0600, 0x06FF), (0x0750, 0x077F), (0x08A0, 0x08FF), (0xFB50, 0xFDFF), (0xFE70, 0xFEFF)]
GURMUKHI = (0x0A00, 0x0A7F)
DEVANAGARI = (0x0900, 0x097F)


def _in(cp, block):
    return block[0] <= cp <= block[1]


def script_stats(text):
    arab = gurm = deva = latin = 0
    for ch in text:
        if not ch.isalpha():
            continue
        cp = ord(ch)
        if any(_in(cp, b) for b in ARABIC_BLOCKS):
            arab += 1
        elif _in(cp, GURMUKHI):
            gurm += 1
        elif _in(cp, DEVANAGARI):
            deva += 1
        elif ch.isascii():
            latin += 1
    return {"arab": arab, "gurmukhi": gurm, "devanagari": deva, "latin": latin}


def check_item(item, schema, strict):
    problems = []
    if jsonschema is not None:
        try:
            jsonschema.validate(item, schema)
        except jsonschema.ValidationError as e:
            problems.append(f"schema: {e.message}")
    for field in ("prompt", "reference", "context"):
        val = item.get(field)
        if not val:
            continue
        s = script_stats(val)
        if s["gurmukhi"] or s["devanagari"]:
            problems.append(f"{field}: Gurmukhi/Devanagari characters found (script leakage)")
        total = s["arab"] + s["latin"]
        if total and s["arab"] / total < 0.6 and item.get("task") != "translation":
            problems.append(f"{field}: only {s['arab']}/{total} alphabetic chars in Arabic script")
        if unicodedata.normalize("NFC", val) != val:
            problems.append(f"{field}: not NFC-normalised")
    if strict and (item.get("validated_by", 0) < 2 or not item.get("adjudicated")):
        problems.append("not fully validated (needs validated_by>=2 and adjudicated)")
    return problems


def main(argv=None):
    ap = argparse.ArgumentParser()
    ap.add_argument("path")
    ap.add_argument("--schema", default=str(Path(__file__).resolve().parents[2] / "schema" / "item.schema.json"))
    ap.add_argument("--strict", action="store_true", help="require fully validated items")
    args = ap.parse_args(argv)
    schema = json.loads(Path(args.schema).read_text(encoding="utf-8"))
    seen_ids, seen_prompts, n, bad = set(), set(), 0, 0
    for lineno, line in enumerate(Path(args.path).read_text(encoding="utf-8").splitlines(), 1):
        if not line.strip():
            continue
        n += 1
        try:
            item = json.loads(line)
        except json.JSONDecodeError as e:
            print(f"line {lineno}: invalid JSON ({e})"); bad += 1; continue
        problems = check_item(item, schema, args.strict)
        if item.get("id") in seen_ids:
            problems.append("duplicate id")
        if item.get("prompt") in seen_prompts:
            problems.append("duplicate prompt")
        seen_ids.add(item.get("id")); seen_prompts.add(item.get("prompt"))
        if problems:
            bad += 1
            print(f"line {lineno} [{item.get('id')}]: " + "; ".join(problems))
    print(f"{n} items, {n - bad} ok, {bad} with problems")
    return 1 if bad else 0


if __name__ == "__main__":
    sys.exit(main())
