from __future__ import annotations

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


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_PATH = ROOT / "Temp" / "rule_lifecycle_policy.json"


def load_json(path: Path) -> dict[str, Any]:
    payload = json.loads(path.read_text(encoding="utf-8"))
    if not isinstance(payload, dict):
        raise ValueError("policy payload must be object")
    return payload


def main() -> int:
    parser = argparse.ArgumentParser(description="Validate rule_lifecycle_policy.json schema and action consistency.")
    parser.add_argument("--json", default=str(DEFAULT_PATH))
    args = parser.parse_args()

    path = Path(args.json)
    if not path.is_absolute():
        path = ROOT / path

    payload = load_json(path)
    errors: list[str] = []

    if not payload.get("as_of"):
        errors.append("missing as_of")
    if not str(payload.get("schema_version") or "").startswith("2026-05-22-rule-lifecycle-v1"):
        errors.append("schema_version mismatch")

    summary = payload.get("summary")
    if not isinstance(summary, dict):
        errors.append("summary must be object")
        summary = {}
    actions_count = summary.get("actions_count")
    if not isinstance(actions_count, dict):
        errors.append("summary.actions_count must be object")
        actions_count = {}

    rows = payload.get("rule_lifecycle_rows")
    if not isinstance(rows, list):
        errors.append("rule_lifecycle_rows must be list")
        rows = []

    allowed_actions = {"KEEP", "WATCH", "DEMOTE", "RETIRE"}
    allowed_states = {"ACTIVE", "SHADOW", "DEPRECATED", "RETIRED"}
    counted: dict[str, int] = {k: 0 for k in allowed_actions}
    for idx, row in enumerate(rows):
        if not isinstance(row, dict):
            errors.append(f"row[{idx}] must be object")
            continue
        action = str(row.get("policy_action") or "")
        state = str(row.get("rule_state") or "")
        if action not in allowed_actions:
            errors.append(f"row[{idx}].policy_action invalid: {action}")
        else:
            counted[action] += 1
        if state not in allowed_states:
            errors.append(f"row[{idx}].rule_state invalid: {state}")
        for key in ("rule_key", "policy_reason"):
            if not str(row.get(key) or "").strip():
                errors.append(f"row[{idx}].{key} missing")
        samples = row.get("samples_t1")
        if not isinstance(samples, int) or samples < 0:
            errors.append(f"row[{idx}].samples_t1 invalid")
        mismatch = row.get("mismatch_rate_t1_pct")
        if mismatch is not None and (not isinstance(mismatch, (int, float)) or mismatch < 0 or mismatch > 100):
            errors.append(f"row[{idx}].mismatch_rate_t1_pct invalid")

    for action, cnt in counted.items():
        if int(actions_count.get(action, 0)) != cnt:
            errors.append(f"actions_count mismatch for {action}: summary={actions_count.get(action)} rows={cnt}")

    if errors:
        print("RULE_LIFECYCLE_POLICY_INVALID")
        print(json.dumps({"errors": errors}, ensure_ascii=False, indent=2))
        return 1

    print("RULE_LIFECYCLE_POLICY_OK")
    print(json.dumps({"rows": len(rows), "actions_count": actions_count}, ensure_ascii=False, indent=2))
    return 0


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