"""B-1 PR② — 매핑·시리즈·payload 순수 단위 테스트 (plan safety-library-1).

법령명 매핑 단위 테스트 = R8-B1 동반 계약 (검증(PR③) 전에 스윕이 도는 만큼
매핑은 코드 레벨 선고정). 실 title 표본 = 2026-06-13 prod documents 실측 형태.
"""

import gzip
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent / "app"))

from workers.statute_adapters.kr import parse_service_payloads  # noqa: E402
from workers.statute_collector import (  # noqa: E402
    legacy_law_name,
    normalize_law_name,
    series_suffix,
)

FIX = Path(__file__).parent / "fixtures" / "statute_kr"


# ─── 법령명 매핑 (실 title 표본) ───

def test_legacy_law_name_extraction():
    # prod 실측 형태: '법령명 (YYYYMMDD) 섹션'
    assert legacy_law_name("건설기술 진흥법 시행규칙 (20260611) 제6장_보칙") == "건설기술 진흥법 시행규칙"
    assert legacy_law_name("산업안전보건법 (20260219) 전문") == "산업안전보건법"
    assert legacy_law_name("패턴 불일치 제목") is None


def test_mapping_equality_not_prefix():
    """prefix 비교 금지 — '산업안전보건법' family 가 시행령 레거시를 오폭하면 안 됨."""
    name = legacy_law_name("산업안전보건법 시행령 (20260324) 제1장")
    assert name == "산업안전보건법 시행령"
    assert normalize_law_name(name) != normalize_law_name("산업안전보건법")
    assert normalize_law_name(name) == normalize_law_name("산업안전보건법 시행령")


def test_mapping_absorbs_middle_dot_and_space():
    """가운뎃점·공백 변형 흡수 — 유해ㆍ위험작업(정식) vs 유해위험작업(law_monitor 표기)."""
    assert (normalize_law_name("유해ㆍ위험작업의 취업 제한에 관한 규칙")
            == normalize_law_name("유해위험작업의 취업 제한에 관한 규칙"))
    assert (normalize_law_name("산업안전보건기준에 관한 규칙")
            == normalize_law_name("산업안전보건기준에관한규칙"))


# ─── 버전 시리즈 식별자 (R7-B1 a) ───

def test_series_suffix():
    assert series_suffix("283449") is None                       # primary
    assert series_suffix("273603|별표0001-00") == "별표0001-00"  # annex (구분 차원 포함)
    assert series_suffix("273603|서식0003-00") == "서식0003-00"


# ─── fetch_version payload (fixture — R4-M4 리스트 계약) ───

def _read_gz(name: str) -> str:
    return gzip.decompress((FIX / name).read_bytes()).decode("utf-8")


def test_parse_service_payloads_rule_with_annexes():
    payloads = parse_service_payloads(
        _read_gz("lawservice_rule.xml.gz"), "산업안전보건기준에 관한 규칙", "273603")
    assert payloads[0].law_doc_kind == "primary"
    assert payloads[0].version_key == "273603"
    assert len(payloads[0].content) > 100_000          # 853조 본문
    annexes = [p for p in payloads if p.law_doc_kind == "annex"]
    # 별표단위 23 중 삭제 tombstone 3 skip(별표10 '삭제 <2023.11.14>'·서식1·2 '삭제 <2012.3.5>')
    # — KR 별표/서식 삭제 = absence 아닌 명시 tombstone (R7-M3 absence 추론 불요의 fixture 증거)
    assert len(annexes) == 20
    keys = [p.version_key for p in annexes]
    assert len(keys) == len(set(keys)), "annex version_key 유일성 (uq_legal_meta_version 전제)"
    assert all(k.startswith("273603|") for k in keys)
    # 구분 차원 — 별표1 vs 서식N 공존 (fixture 실측: (번호,가지)만으로는 4건 충돌)
    assert any("별표" in k for k in keys) and any("서식" in k for k in keys)


def test_parse_service_payloads_sanab_no_annex():
    payloads = parse_service_payloads(
        _read_gz("lawservice_sanab.xml.gz"), "산업안전보건법", "283449")
    assert len(payloads) == 1                          # 별표 없는 법령 = primary 단독
    p = payloads[0]
    assert p.promulgation_date == "20260219"
    assert p.effective_date == "20260601"
    assert "제2조(정의)" in p.content                  # 조문내용 보존
    assert p.content.startswith("# 산업안전보건법")
