"""
Persistence and integrity verification tests for Flex-O entities.
Ensures fingerprints survive JSON export/import and detect tampering.
"""
import json
import pytest

from flexoentity import EntityState
from builder.questions import RadioQuestion, AnswerOption


# ──────────────────────────────────────────────────────────────────────────────
@pytest.fixture
def approved_question(domain):
    """Provide a fully approved and published RadioQuestion for persistence tests."""
    q = RadioQuestion(
        domain=domain,
        etype=None,  # RadioQuestion sets this internally to EntityType.QUESTION
        state=EntityState.DRAFT,
        text="What is Ohm’s law?",
        options=[
            AnswerOption(text="U = R × I", points=1),
            AnswerOption(text="U = I / R", points=0),
            AnswerOption(text="R = U × I", points=0),
        ],
    )
    q.approve()
    q.sign()
    q.publish()
    return q


@pytest.mark.skip(reason="FlexOIDs regenerated on import; enable once JSON format is stable")
def test_json_roundtrip_preserves_integrity(approved_question):
    """
    Export to JSON and reload — ensure fingerprints and signatures remain valid.
    """
    json_str = approved_question.to_json()
    loaded = RadioQuestion.from_json(json_str)

    # Fingerprint and state should match — integrity must pass
    assert RadioQuestion.verify_integrity(loaded)

    # Metadata should be preserved exactly
    assert approved_question.signature == loaded.signature
    assert approved_question.flexo_id == loaded.flexo_id
    assert loaded.state == approved_question.state


# ──────────────────────────────────────────────────────────────────────────────

@pytest.mark.skip(reason="FlexOIDs regenerated on import; tampering detection not yet implemented")
def test_json_tampering_detection(approved_question):
    """Tampering with content should invalidate fingerprint verification."""
    json_str = approved_question.to_json()
    tampered = json.loads(json_str)
    tampered["text"] = "Tampered content injection"
    tampered_json = json.dumps(tampered)

    loaded = RadioQuestion.from_json(tampered_json)
    assert not RadioQuestion.verify_integrity(loaded)


# ──────────────────────────────────────────────────────────────────────────────

@pytest.mark.skip(reason="FlexOIDs regenerated on import; corruption detection not yet applicable")
def test_json_file_corruption(approved_question, tmp_path):
    """Simulate file corruption — integrity check must fail."""
    file = tmp_path / "question.json"
    json_str = approved_question.to_json()
    file.write_text(json_str)

    # Corrupt the file (simulate accidental byte modification)
    corrupted = json_str.replace("Ohm’s", "Omm’s")
    file.write_text(corrupted)

    loaded = RadioQuestion.from_json(file.read_text())
    assert not RadioQuestion.verify_integrity(loaded)
