from __future__ import annotations

from osm_lead_source_service.errors import (
    ContractViolation,
    PbfStageContractError,
    bounded_contract_reason,
)


def test_known_contract_reason_is_allowlisted() -> None:
    error = ContractViolation("parsed object contains a duplicate tag key")

    assert bounded_contract_reason(error) == "duplicate_normalized_tag_key"


def test_unknown_contract_reason_is_one_way_and_deterministic() -> None:
    message = "sensitive object-specific value"
    first = bounded_contract_reason(ContractViolation(message))
    second = bounded_contract_reason(ContractViolation(message))

    assert first == second
    assert first.startswith("unknown_")
    assert len(first) == len("unknown_") + 12
    assert message not in first


def test_stage_contract_error_exposes_only_bounded_diagnostic_code() -> None:
    cause = ContractViolation("sensitive object-specific value")
    error = PbfStageContractError("sink_accept", cause)

    assert error.stage == "sink_accept"
    assert error.reason_code.startswith("unknown_")
    assert error.diagnostic_code.startswith("PbfStageContractError:sink_accept:unknown_")
    assert "sensitive" not in error.diagnostic_code
