"""creator_corrections (wave3 제작자 정정 채널) — 결정론 테스트.

핵심 계약: 정정 없음 = 블록 빈 문자열 = 소비 스텝 프롬프트 byte-identical /
malformed = fail-fast (silent skip 금지) / 내용은 데이터 (코드=구조 검증만).
"""
import json

import pytest

from app.core.creator_corrections import (
    corrections_block,
    corrections_path,
    load_creator_corrections,
    project_corrections_block,
    save_creator_corrections,
)
from app.core.errors import AppError


@pytest.fixture()
def proj(tmp_path, monkeypatch):
    from app.core.config import settings
    monkeypatch.setattr(settings, "projects_dir", str(tmp_path))
    return "test-project-0001"


def test_missing_file_is_empty_and_block_is_byte_identical(proj):
    assert load_creator_corrections(proj) == []
    assert project_corrections_block(proj) == ""
    system = "SYSTEM PROMPT BODY"
    assert system + project_corrections_block(proj) == system


def test_roundtrip_save_load_active_filter(proj):
    saved = save_creator_corrections(proj, {"corrections": [
        {"id": "a", "text": "정정 A", "active": True},
        {"id": "b", "text": "정정 B", "active": False},
        {"id": "c", "text": "  정정 C  "},  # active 생략 = True, strip
    ]})
    assert [e["id"] for e in saved] == ["a", "b", "c"]
    active = load_creator_corrections(proj)
    assert [e["id"] for e in active] == ["a", "c"]
    assert active[1]["text"] == "정정 C"
    assert corrections_path(proj).exists()


def test_block_contains_entries_and_header_once(proj):
    save_creator_corrections(proj, {"corrections": [
        {"id": "a", "text": "정정 A", "active": True},
        {"id": "b", "text": "정정 B", "active": True},
    ]})
    block = project_corrections_block(proj)
    assert block.count("CREATOR CORRECTIONS") == 1
    assert "- 정정 A" in block and "- 정정 B" in block
    # inactive 만 남으면 빈 블록
    save_creator_corrections(proj, {"corrections": [
        {"id": "a", "text": "정정 A", "active": False},
    ]})
    assert project_corrections_block(proj) == ""


def test_block_pure_function_empty_list():
    assert corrections_block([]) == ""


@pytest.mark.parametrize("bad", [
    {},                                        # corrections 키 없음
    {"corrections": "not-a-list"},
    {"corrections": [{"id": "", "text": "x"}]},
    {"corrections": [{"id": "a", "text": "  "}]},
    {"corrections": [{"id": "a", "text": "x", "active": "yes"}]},
    {"corrections": ["plain-string"]},
])
def test_malformed_fails_fast_on_save(proj, bad):
    with pytest.raises(AppError):
        save_creator_corrections(proj, bad)


def test_malformed_file_fails_fast_on_load(proj):
    path = corrections_path(proj)
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text("{not json", encoding="utf-8")
    with pytest.raises(AppError):
        load_creator_corrections(proj)
    path.write_text(json.dumps({"corrections": [{"id": "a"}]}), encoding="utf-8")
    with pytest.raises(AppError):
        load_creator_corrections(proj)
