import pytest
from flexoentity import FlexOID, FlexoEntity, EntityType, EntityState


# ──────────────────────────────────────────────────────────────────────────────
# Tests adapted to use real RadioQuestion fixture instead of DummyEntity
# ──────────────────────────────────────────────────────────────────────────────

def test_initial_state(radio_question):
    q = radio_question
    assert q.state == EntityState.DRAFT
    assert q.flexo_id.version == 1
    assert FlexoEntity.verify_integrity(q)


def test_approval_bumps_version(radio_question):
    q = radio_question
    q.approve()
    assert q.state == EntityState.APPROVED
    assert q.flexo_id.version == 2


def test_signing_bumps_version(radio_question):
    q = radio_question
    q.approve()
    v_before = str(q.flexo_id)
    q.sign()
    assert q.state == EntityState.APPROVED_AND_SIGNED
    assert str(q.flexo_id) != v_before


def test_publish_bumps_version(radio_question):
    q = radio_question
    q.approve()
    q.sign()
    v_before = q.flexo_id.version
    q.publish()
    assert q.state == EntityState.PUBLISHED
    assert q.flexo_id.version == v_before + 1


def test_modify_content_changes_fingerprint(radio_question):
    q = radio_question
    q.text = "Rephrased content"  # simulate text change
    changed = q._update_fingerprint()
    assert changed


def test_no_version_bump_on_draft_edits(radio_question):
    q = radio_question
    q.text = "Minor draft edit"
    q._update_fingerprint()
    assert q.flexo_id.version == 1


def test_version_bump_after_edit_and_sign(radio_question):
    q = radio_question
    q.approve()
    v1 = str(q.flexo_id)
    q.text = "Changed content"
    q.sign()
    assert str(q.flexo_id) != v1


def test_integrity_check_passes_and_fails(radio_question):
    q = radio_question
    q.approve()
    assert FlexoEntity.verify_integrity(q)

    # simulate tampering
    q.text = "Tampered text"
    assert not FlexoEntity.verify_integrity(q)


def test_obsolete_state(radio_question):
    q = radio_question
    q.approve()
    q.sign()
    q.publish()
    q.obsolete()
    assert q.state == EntityState.OBSOLETE


def test_clone_new_base_resets_lineage(radio_question):
    q = radio_question
    q.approve()
    q.sign()
    q.publish()
    q.obsolete()
    old_id = str(q.flexo_id)
    q.clone_new_base()
    assert str(q.flexo_id) != old_id
    assert q.state == EntityState.DRAFT
    assert q.flexo_id.version == 1

def test_clone_new_base_sets_origin(radio_question):
    q = radio_question
    q.approve()
    q.sign()
    q.publish()
    old_id = str(q.flexo_id)
    q.obsolete()
    q.clone_new_base()
    assert q.origin == old_id
    assert q.state == EntityState.DRAFT
    assert q.flexo_id.version == 1
    assert q.flexo_id != old_id

def test_mass_version_increments_until_obsolete(radio_question):
    q = radio_question
    q.approve()
    for _ in range(FlexOID.MAX_VERSION - 2):
        q.sign()
    with pytest.raises(RuntimeError, match="mark obsolete"):
        q.sign()
