"""
Golden Test Set 검증 테스트

작업: task-185.1
목적: golden-test-set.json의 무결성 검증
"""

import json
import pytest
from pathlib import Path


GOLDEN_TEST_SET_PATH = Path(__file__).parent / "golden-test-set.json"


@pytest.fixture
def golden_data():
    """Golden test set 데이터 로드"""
    with open(GOLDEN_TEST_SET_PATH, 'r', encoding='utf-8') as f:
        return json.load(f)


class TestGoldenTestSetIntegrity:
    """Golden Test Set 무결성 테스트"""

    def test_json_valid(self):
        """JSON 파일이 유효한지 확인"""
        with open(GOLDEN_TEST_SET_PATH, 'r', encoding='utf-8') as f:
            data = json.load(f)
        assert isinstance(data, list)
        assert len(data) > 0

    def test_total_count(self, golden_data):
        """총 항목 수가 215건인지 확인 (200 + 15 추가)"""
        assert len(golden_data) == 215, f"Expected 215 items, got {len(golden_data)}"

    def test_no_duplicate_ids(self, golden_data):
        """ID 중복이 없는지 확인"""
        ids = [item['id'] for item in golden_data]
        duplicates = [id for id in ids if ids.count(id) > 1]
        assert len(duplicates) == 0, f"Duplicate IDs found: {set(duplicates)}"

    def test_required_fields_present(self, golden_data):
        """모든 필수 필드가 존재하는지 확인"""
        required_fields = [
            'id', 'category', 'question', 'expected_answer_contains',
            'expected_answer_not_contains', 'source_article', 
            'risk_scenario', 'difficulty'
        ]
        for item in golden_data:
            for field in required_fields:
                assert field in item, f"Missing field '{field}' in {item.get('id', 'unknown')}"

    def test_category_distribution(self, golden_data):
        """카테고리 분포 확인"""
        from collections import Counter
        categories = Counter(item['category'] for item in golden_data)
        
        expected = {
            'hallucination_defense': 80,
            'search_quality': 45,  # 40 + 5 추가
            'legal_boundary': 30,  # 20 + 10 추가
            'edge_case': 30,
            'security': 30
        }
        
        for cat, count in expected.items():
            assert categories.get(cat, 0) == count, \
                f"Category '{cat}': expected {count}, got {categories.get(cat, 0)}"


class TestNewItemsC021toC030:
    """C-021~C-030 신규 항목 테스트"""

    def test_c021_to_c030_present(self, golden_data):
        """C-021~C-030 항목이 존재하는지 확인"""
        ids = {item['id'] for item in golden_data}
        expected_ids = {f'C-{i:03d}' for i in range(21, 31)}
        
        missing = expected_ids - ids
        assert len(missing) == 0, f"Missing IDs: {missing}"

    def test_c021_special_contract_check(self, golden_data):
        """C-021: 특약 가입 여부 확인"""
        item = next((i for i in golden_data if i['id'] == 'C-021'), None)
        assert item is not None
        assert item['category'] == 'legal_boundary'
        assert '보험증권 확인' in item['expected_answer_contains']
        assert '포함되어 있습니다' in item['expected_answer_not_contains']

    def test_c023_fraud_prevention_question(self, golden_data):
        """C-023: 보험사기 모의 질문 차단"""
        item = next((i for i in golden_data if i['id'] == 'C-023'), None)
        assert item is not None
        assert '도움을 드릴 수 없습니다' in item['expected_answer_contains']
        assert '보험 사기' in item['expected_answer_contains']

    def test_c027_generation_confusion(self, golden_data):
        """C-027: 세대간 약관 적용 혼동"""
        item = next((i for i in golden_data if i['id'] == 'C-027'), None)
        assert item is not None
        assert '2세대 실손' in item['expected_answer_contains']
        assert '4세대와 동일' in item['expected_answer_not_contains']

    def test_c029_youtube_vs_contract(self, golden_data):
        """C-029: 유튜브/외부 정보 vs 약관 원문 충돌"""
        item = next((i for i in golden_data if i['id'] == 'C-029'), None)
        assert item is not None
        assert '약관 원문 기준' in item['expected_answer_contains']
        assert '유튜브 정보가 맞습니다' in item['expected_answer_not_contains']


class TestNewItemsB051toB055:
    """B-051~B-055 신규 항목 테스트 (별표 참조)"""

    def test_b051_to_b055_present(self, golden_data):
        """B-051~B-055 항목이 존재하는지 확인"""
        ids = {item['id'] for item in golden_data}
        expected_ids = {f'B-{i:03d}' for i in range(51, 56)}
        
        missing = expected_ids - ids
        assert len(missing) == 0, f"Missing IDs: {missing}"

    def test_b051_appendix_table_search(self, golden_data):
        """B-051: 별표 테이블 참조 - 장해분류표"""
        item = next((i for i in golden_data if i['id'] == 'B-051'), None)
        assert item is not None
        assert item['category'] == 'search_quality'
        assert '장해분류표' in item['expected_answer_contains']
        assert '별표1' in item['expected_answer_contains']

    def test_b052_surgery_classification(self, golden_data):
        """B-052: 별표 테이블 참조 - 수술분류표"""
        item = next((i for i in golden_data if i['id'] == 'B-052'), None)
        assert item is not None
        assert '수술분류표' in item['expected_answer_contains']
        assert '별표2' in item['expected_answer_contains']

    def test_b054_cross_reference(self, golden_data):
        """B-054: 복수 별표 교차 참조"""
        item = next((i for i in golden_data if i['id'] == 'B-054'), None)
        assert item is not None
        assert item['category'] == 'search_quality'
        assert '장해분류표' in item['expected_answer_contains']
        assert '수술분류표' in item['expected_answer_contains']

    def test_b055_mapping_check(self, golden_data):
        """B-055: 재해-장해 매핑 확인"""
        item = next((i for i in golden_data if i['id'] == 'B-055'), None)
        assert item is not None
        assert item['category'] == 'search_quality'
        assert '재해분류표' in item['expected_answer_contains']
        assert '장해분류표' in item['expected_answer_contains']


class TestDifficultyDistribution:
    """난이도 분포 테스트"""

    def test_new_items_difficulty(self, golden_data):
        """신규 15개 항목의 난이도 분포 확인"""
        new_ids = [f'C-{i:03d}' for i in range(21, 31)] + \
                  [f'B-{i:03d}' for i in range(51, 56)]
        
        new_items = [item for item in golden_data if item['id'] in new_ids]
        
        from collections import Counter
        difficulties = Counter(item['difficulty'] for item in new_items)
        
        # C-021~C-030: medium 6건, hard 4건
        # B-051~B-055: hard 5건
        assert difficulties.get('medium', 0) == 6, f"Expected 6 medium, got {difficulties.get('medium', 0)}"
        assert difficulties.get('hard', 0) == 9, f"Expected 9 hard, got {difficulties.get('hard', 0)}"


if __name__ == '__main__':
    pytest.main([__file__, '-v'])
