import pytest

from src.domain.project_auth.source_authority import (
    IDENTIFIER_SEMANTICS_MISMATCH,
    INSUFFICIENT_EVIDENCE,
    IN_SYNC,
    PUBLICATION_INCOMPLETE,
    CORE_POINTER_STALE,
    classify_source_authority,
    require_migration_source,
)


def test_preview_revision_is_not_stale_when_main_is_older():
    observation = classify_source_authority(
        generated_ref="preview",
        generated_sha="preview-sha",
        publication_ref="main",
        publication_sha="main-sha",
        reachable_refs={"preview": "preview-sha", "main": "main-sha"},
    )

    assert observation.classification == PUBLICATION_INCOMPLETE
    assert require_migration_source(observation) == ("preview", "preview-sha")


def test_same_commit_is_synchronized():
    observation = classify_source_authority(
        generated_ref="preview",
        generated_sha="same",
        publication_ref="main",
        publication_sha="same",
        reachable_refs={"preview": "same", "main": "same"},
    )
    assert observation.classification == IN_SYNC


def test_unreachable_core_sha_is_pointer_stale():
    observation = classify_source_authority(
        generated_ref="preview",
        generated_sha="missing",
        publication_ref="main",
        publication_sha="main",
        reachable_refs={"preview": "preview", "main": "main"},
    )
    assert observation.classification == CORE_POINTER_STALE
    with pytest.raises(ValueError, match="not_safe"):
        require_migration_source(observation)


def test_known_commit_on_unconfigured_ref_is_identifier_mismatch():
    observation = classify_source_authority(
        generated_ref="preview",
        generated_sha="codegen",
        publication_ref="main",
        publication_sha="main",
        reachable_refs={"preview": "preview", "main": "main", "codegen/run": "codegen"},
    )
    assert observation.classification == IDENTIFIER_SEMANTICS_MISMATCH


def test_missing_authority_inputs_are_insufficient():
    observation = classify_source_authority(
        generated_ref="preview",
        generated_sha=None,
        publication_ref="main",
        publication_sha="main",
    )
    assert observation.classification == INSUFFICIENT_EVIDENCE
