"""
test_docling_comparison.py - opendataloader-pdf 파싱 품질 검증 테스트

Task-735.1 서브태스크: 아르고스(테스터) 수행
대상 PDF: 금융소비자_보호에_관한_법률법률제21065호20260102.pdf

검증 항목:
1. 텍스트 추출 정확도 (텍스트 길이)
2. 표(table) 구조 보존 여부 (표 개수)
3. 조항 번호 정확성 (제N조 패턴)
4. 특수문자 처리 (「」 ㆍ ① ② ③ · → 등)
5. 처리 속도 (초 단위)
"""

import json
import re
import sys
import time

sys.path.insert(0, "/home/jay/workspace/libs")
from doc_parser import parse_pdf

PDF_PATH = "/home/jay/.cokacdir/workspace/autoset/금융소비자_보호에_관한_법률법률제21065호20260102.pdf"
RESULT_PATH = "/home/jay/workspace/teams/dev2/tests/comparison_result.json"

# 검증 대상 특수문자 목록
SPECIAL_CHARS = {
    "「": "여는 꺾쇠괄호",
    "」": "닫는 꺾쇠괄호",
    "『": "겹 여는 꺾쇠괄호",
    "』": "겹 닫는 꺾쇠괄호",
    "ㆍ": "가운뎃점(한글)",
    "·": "가운뎃점(중점)",
    "①": "원형 숫자 1",
    "②": "원형 숫자 2",
    "③": "원형 숫자 3",
    "④": "원형 숫자 4",
    "⑤": "원형 숫자 5",
    "⑥": "원형 숫자 6",
    "⑦": "원형 숫자 7",
    "⑧": "원형 숫자 8",
    "⑨": "원형 숫자 9",
    "⑩": "원형 숫자 10",
    "→": "오른쪽 화살표",
    "※": "참고 표시",
    "○": "빈 동그라미",
    "●": "채운 동그라미",
}


def count_special_chars(text: str) -> dict:
    """텍스트에서 특수문자 개수를 카운트한다."""
    counts = {}
    for char, desc in SPECIAL_CHARS.items():
        count = text.count(char)
        if count > 0:
            counts[char] = {"description": desc, "count": count}
    return counts


def extract_clause_numbers(text: str) -> list:
    """제N조 패턴으로 조항 번호를 추출한다."""
    pattern = r"제\d+조"
    matches = re.findall(pattern, text)
    # 중복 제거 후 정렬
    unique_matches = sorted(set(matches), key=lambda x: int(re.search(r"\d+", x).group()))  # type: ignore[union-attr]
    return unique_matches


def run_comparison():
    """opendataloader-pdf 파싱 품질 검증을 실행한다."""
    print("=" * 70)
    print("opendataloader-pdf 파싱 품질 검증 시작")
    print(f"대상 PDF: {PDF_PATH}")
    print("=" * 70)

    # PDF 파일 읽기
    with open(PDF_PATH, "rb") as f:
        pdf_bytes = f.read()

    print(f"\nPDF 파일 크기: {len(pdf_bytes):,} bytes ({len(pdf_bytes)/1024:.1f} KB)")

    # opendataloader-pdf 파싱
    print("\n[1/1] opendataloader-pdf 파싱 중...")
    start = time.time()
    result = parse_pdf(pdf_bytes)
    elapsed = time.time() - start
    print(f"    완료: {elapsed:.2f}초")

    odl_text = result.text or ""
    odl_tables = result.tables or []
    odl_page_count = result.metadata.get("page_count", 0)

    # =========================================================
    # 항목별 분석 (5개 항목, 단독 검증)
    # =========================================================
    print("\n" + "=" * 70)
    print("품질 검증 결과")
    print("=" * 70)

    results = {}

    # ----------------------------------------------------------
    # 1. 텍스트 추출 정확도
    # ----------------------------------------------------------
    print("\n[항목 1] 텍스트 추출 정확도")
    print("-" * 50)
    odl_text_len = len(odl_text)

    print(f"  opendataloader-pdf 텍스트 길이: {odl_text_len:,} 문자")
    print(f"  페이지 수: {odl_page_count}페이지")

    if odl_text_len > 0:
        print(f"  텍스트 샘플 (처음 200자):\n    {odl_text[:200]}")

    results["1_text_accuracy"] = {
        "odl_text_length": odl_text_len,
        "odl_page_count": odl_page_count,
        "note": "opendataloader-pdf 단독 텍스트 추출 결과",
    }

    # ----------------------------------------------------------
    # 2. 표(table) 구조 보존 여부
    # ----------------------------------------------------------
    print("\n[항목 2] 표(table) 구조 보존 여부")
    print("-" * 50)
    odl_table_count = len(odl_tables)

    odl_table_cells = sum(len(t.get("headers", [])) + sum(len(r) for r in t.get("rows", [])) for t in odl_tables)

    print(f"  opendataloader-pdf 추출 표 수: {odl_table_count}개 (총 셀 수: {odl_table_cells})")

    if odl_tables:
        print(f"\n  첫 번째 표 미리보기:")
        first_table = odl_tables[0]
        print(f"    헤더: {first_table.get('headers', [])[:5]}")
        for i, row in enumerate(first_table.get("rows", [])[:3]):
            print(f"    행 {i+1}: {row[:5]}")

    results["2_table_preservation"] = {
        "odl_table_count": odl_table_count,
        "odl_total_cells": odl_table_cells,
        "note": "opendataloader-pdf 단독 표 구조 추출 결과",
    }

    # ----------------------------------------------------------
    # 3. 조항 번호 정확성
    # ----------------------------------------------------------
    print("\n[항목 3] 조항 번호 정확성 (제N조 패턴)")
    print("-" * 50)
    odl_clauses = extract_clause_numbers(odl_text)
    odl_clause_set = set(odl_clauses)

    print(f"  opendataloader-pdf 추출 조항 수: {len(odl_clauses)}개 (고유: {len(odl_clause_set)}개)")
    print(f"  조항 목록 (처음 15개): {odl_clauses[:15]}")

    results["3_clause_accuracy"] = {
        "odl_clause_count": len(odl_clauses),
        "odl_unique_clause_count": len(odl_clause_set),
        "all_odl_clauses": odl_clauses,
        "note": "opendataloader-pdf 단독 조항 번호 추출 결과",
    }

    # ----------------------------------------------------------
    # 4. 특수문자 처리
    # ----------------------------------------------------------
    print("\n[항목 4] 특수문자 처리")
    print("-" * 50)
    odl_special = count_special_chars(odl_text)

    odl_special_total = sum(v["count"] for v in odl_special.values())
    odl_special_types = len(odl_special)

    print(f"  opendataloader-pdf 특수문자 종류: {odl_special_types}종 / 총 개수: {odl_special_total}개")
    print()

    print(f"  {'문자':<6} {'설명':<20} {'횟수':>10}")
    print(f"  {'-'*6} {'-'*20} {'-'*10}")
    for char, info in odl_special.items():
        print(f"  {char:<6} {info['description']:<20} {info['count']:>10}")

    results["4_special_chars"] = {
        "odl_special_char_types": odl_special_types,
        "odl_special_char_total": odl_special_total,
        "odl_detail": {k: v["count"] for k, v in odl_special.items()},
        "note": "opendataloader-pdf 단독 특수문자 처리 결과",
    }

    # ----------------------------------------------------------
    # 5. 처리 속도
    # ----------------------------------------------------------
    print("\n[항목 5] 처리 속도")
    print("-" * 50)

    pages_per_sec = odl_page_count / elapsed if elapsed > 0 and odl_page_count > 0 else 0.0

    print(f"  opendataloader-pdf 처리 시간: {elapsed:.3f}초")
    print(
        f"  총 페이지: {odl_page_count}페이지 / 페이지당: {elapsed/odl_page_count:.4f}초"
        if odl_page_count > 0
        else f"  총 페이지: 미확인"
    )

    results["5_processing_speed"] = {
        "odl_time_seconds": round(elapsed, 4),
        "odl_page_count": odl_page_count,
        "odl_pages_per_second": round(pages_per_sec, 4),
        "note": "opendataloader-pdf 단독 처리 속도 결과",
    }

    # ----------------------------------------------------------
    # 종합 요약
    # ----------------------------------------------------------
    print("\n" + "=" * 70)
    print("종합 요약")
    print("=" * 70)
    print(f"\n  텍스트 길이      : {odl_text_len:,} 문자")
    print(f"  페이지 수        : {odl_page_count}페이지")
    print(f"  추출 표 수       : {odl_table_count}개 (총 셀: {odl_table_cells})")
    print(f"  감지 조항 수     : {len(odl_clauses)}개 (고유: {len(odl_clause_set)}개)")
    print(f"  특수문자 종류    : {odl_special_types}종 / 총 {odl_special_total}개")
    print(f"  처리 시간        : {elapsed:.3f}초")

    results["overall"] = {
        "odl_text_length": odl_text_len,
        "odl_page_count": odl_page_count,
        "odl_table_count": odl_table_count,
        "odl_total_cells": odl_table_cells,
        "odl_clause_count": len(odl_clauses),
        "odl_unique_clause_count": len(odl_clause_set),
        "odl_special_char_types": odl_special_types,
        "odl_special_char_total": odl_special_total,
        "odl_time_seconds": round(elapsed, 4),
        "test_info": {
            "pdf_path": PDF_PATH,
            "pdf_size_bytes": len(pdf_bytes),
            "test_date": time.strftime("%Y-%m-%d %H:%M:%S"),
        },
    }

    # =========================================================
    # 결과를 JSON으로 저장
    # =========================================================
    with open(RESULT_PATH, "w", encoding="utf-8") as f:
        json.dump(results, f, ensure_ascii=False, indent=2)

    print(f"\n결과 JSON 저장 완료: {RESULT_PATH}")
    print("=" * 70)

    return results


if __name__ == "__main__":
    run_comparison()
