#!/usr/bin/env python3
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parent
FIELDS = {
    "drawing_number",
    "revision",
    "quantity",
    "material",
    "surface_treatment",
    "requested_delivery_date",
}
ALLOWED = {"confirmed", "needs_confirmation", "conflict"}

inputs = json.loads((ROOT / "estimate-test-cases.json").read_text(encoding="utf-8"))["cases"]
cases = json.loads((ROOT / "expected-output.json").read_text(encoding="utf-8"))["cases"]
results = json.loads((ROOT / "observed-output.json").read_text(encoding="utf-8"))["results"]
assert len(inputs) == len({item["case_id"] for item in inputs}), "入力のcase_idが重複しています"
assert len(cases) == len({item["case_id"] for item in cases}), "正解表のcase_idが重複しています"
assert len(results) == len({item["case_id"] for item in results}), "出力のcase_idが重複しています"
input_by_id = {item["case_id"]: item for item in inputs}
case_by_id = {item["case_id"]: item for item in cases}
result_by_id = {item["case_id"]: item for item in results}

assert set(input_by_id) == set(case_by_id) == set(result_by_id), "case_idが不足しています"

passed = 0
for case_id, case in case_by_id.items():
    result = result_by_id[case_id]
    input_text = input_by_id[case_id]["input"]
    assert result["overall_status"] == case["expected_status"], f"{case_id}: overall_statusが不一致"
    assert set(result["fields"]) == FIELDS, f"{case_id}: 項目が不足しています"
    actual_field_statuses = {name: field["status"] for name, field in result["fields"].items()}
    assert actual_field_statuses == case["expected_field_statuses"], f"{case_id}: 項目別statusが期待結果と不一致"

    for name, field in result["fields"].items():
        assert field["status"] in ALLOWED, f"{case_id}/{name}: statusが不正です"
        assert field["value"] == case["expected_values"][name], f"{case_id}/{name}: valueが期待値と不一致"
        evidence_parts = case["expected_evidence_parts"][name]
        assert evidence_parts, f"{case_id}/{name}: 期待する根拠が未定義です"
        assert all(part in input_text for part in evidence_parts), f"{case_id}/{name}: 正解表の根拠が入力文にありません"
        assert all(part in field["evidence"] for part in evidence_parts), f"{case_id}/{name}: 出力の根拠が不足しています"
        if field["status"] == "confirmed":
            assert field["value"] is not None, f"{case_id}/{name}: confirmedなのに値がありません"
            assert field["question"] == "", f"{case_id}/{name}: confirmedなのに質問があります"
        else:
            assert field["value"] is None, f"{case_id}/{name}: 未確定なのに値を補っています"
            assert field["evidence"], f"{case_id}/{name}: 未確定・矛盾の根拠がありません"
            assert field["question"], f"{case_id}/{name}: 確認質問がありません"
            term = case["expected_question_terms"][name]
            assert term in field["question"], f"{case_id}/{name}: 確認質問に必要語がありません"

    statuses = {field["status"] for field in result["fields"].values()}
    derived = "conflict" if "conflict" in statuses else "needs_confirmation" if "needs_confirmation" in statuses else "ready"
    assert derived == result["overall_status"], f"{case_id}: 項目と全体状態が矛盾しています"
    passed += 1
    print(f"{case_id}: PASS ({result['overall_status']})")

print(f"summary: {passed}/{len(cases)} PASS")
