import json, csv, os, sys, hashlib
from pathlib import Path

SCHEMA = ["id", "active_kind", "active_json_type", "active_value", "active_json"]

def classify_value(val):
    if isinstance(val, bool):
        kind = "boolean"
        json_type = "boolean"
        value = "true" if val else "false"
    elif isinstance(val, str):
        if val in ("true", "false"):
            kind = "string_boolean_literal"
            json_type = "string"
            value = val
        else:
            kind = "string_other"
            json_type = "string"
            value = val
    elif val is None:
        kind = "null"
        json_type = "null"
        value = "null"
    elif isinstance(val, int):
        kind = "number"
        json_type = "number"
        value = str(val)
    elif isinstance(val, float):
        kind = "number"
        json_type = "number"
        value = json.dumps(val)
    else:
        kind = type(val).__name__
        json_type = type(val).__name__
        value = json.dumps(val, ensure_ascii=False)
    return kind, json_type, value

def export_explicit(source_path, csv_path, naive_path):
    with open(source_path, "r", encoding="utf-8") as f:
        raw_text = f.read()
    records = json.loads(raw_text)

    rows = []
    for rec in records:
        row = {col: "" for col in SCHEMA}
        row["id"] = rec["id"]
        val = rec["active"]
        kind, json_type, value = classify_value(val)
        row["active_kind"] = kind
        row["active_json_type"] = json_type
        row["active_value"] = value
        row["active_json"] = json.dumps(val, ensure_ascii=False)
        rows.append(row)

    with open(csv_path, "x", encoding="utf-8", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=SCHEMA)
        writer.writeheader()
        writer.writerows(rows)

    # naive export
    naive_schema = ["id", "active"]
    naive_rows = []
    for rec in records:
        val = rec["active"]
        if isinstance(val, bool):
            naive_rows.append({"id": rec["id"], "active": "true" if val else "false"})
        elif val is None:
            naive_rows.append({"id": rec["id"], "active": ""})
        else:
            naive_rows.append({"id": rec["id"], "active": str(val)})
    with open(naive_path, "x", encoding="utf-8", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=naive_schema)
        writer.writeheader()
        writer.writerows(naive_rows)

    # read-back verification
    with open(csv_path, "r", encoding="utf-8", newline="") as f:
        reader = csv.DictReader(f)
        csv_rows = list(reader)

    checks_passed = 0
    checks_total = 0
    for csv_row, src_rec in zip(csv_rows, records):
        val = src_rec["active"]
        exp_kind, exp_type, exp_value = classify_value(val)
        exp_json = json.dumps(val, ensure_ascii=False)
        checks_total += 5
        if csv_row["id"] == src_rec["id"]:
            checks_passed += 1
        if csv_row["active_kind"] == exp_kind:
            checks_passed += 1
        if csv_row["active_json_type"] == exp_type:
            checks_passed += 1
        if csv_row["active_value"] == exp_value:
            checks_passed += 1
        if csv_row["active_json"] == exp_json:
            checks_passed += 1

    source_bytes = raw_text.encode("utf-8")
    with open(csv_path, "rb") as f:
        csv_bytes = f.read()

    evidence = {
        "fixture_path": str(source_path),
        "output_path": str(csv_path),
        "naive_path": str(naive_path),
        "python_version": sys.version,
        "source_sha256": hashlib.sha256(source_bytes).hexdigest(),
        "source_bytes": len(source_bytes),
        "csv_sha256": hashlib.sha256(csv_bytes).hexdigest(),
        "csv_bytes": len(csv_bytes),
        "data_rows": len(records),
        "columns": len(SCHEMA),
        "checks_passed": checks_passed,
        "checks_total": checks_total,
        "all_checks_passed": checks_passed == checks_total,
        "rows": [
            {
                "id": row["id"],
                "active_kind": row["active_kind"],
                "active_json_type": row["active_json_type"],
                "active_value": row["active_value"],
                "active_json": row["active_json"],
            }
            for row in rows
        ],
    }
    return evidence

if __name__ == "__main__":
    base = Path(sys.argv[1]).parent if len(sys.argv) > 1 else Path(".")
    src = str(base / "boolean-vs-string-fixture.json") if len(sys.argv) <= 1 else sys.argv[1]
    out = sys.argv[2] if len(sys.argv) > 2 else str(base / "boolean-vs-string-output.csv")
    naive = sys.argv[3] if len(sys.argv) > 3 else str(base / "boolean-vs-string-naive.csv")
    evi = sys.argv[4] if len(sys.argv) > 4 else str(base / "boolean-vs-string-evidence.json")
    evidence = export_explicit(src, out, naive)
    with open(evi, "x", encoding="utf-8") as f:
        json.dump(evidence, f, indent=2, ensure_ascii=False)
    print(f"Export complete: {evidence['data_rows']} rows, {evidence['columns']} cols, "
          f"{evidence['checks_passed']}/{evidence['checks_total']} checks passed, "
          f"CSV {evidence['csv_bytes']} bytes")
