from enum import Enum


class OcrFailureCode(str, Enum):
    """Machine-readable reason an OCR call failed, for callers to act on."""

    # The library or its environment is misconfigured (missing API key, bad
    # processor id, credentials without access) -- not something a caller can
    # retry without an engineering fix.
    CONFIGURATION_ERROR = "configuration_error"

    # The provider rejected the file itself (corrupted, unsupported mime type,
    # unreadable content) -- caller should have the source re-uploaded.
    UNSUPPORTED_FILE = "unsupported_file"

    # The provider call failed for reasons unrelated to the file (timeout,
    # quota exhaustion, service unavailable) -- usually worth retrying later.
    PROVIDER_ERROR = "provider_error"

    # The provider call succeeded but produced no usable structured data
    # (schema mismatch, empty response) -- the page may be blank or the model
    # couldn't extract anything from it.
    NO_DATA_EXTRACTED = "no_data_extracted"

    # Data was extracted but failed internal consistency validation (e.g. row
    # time-ordering, a value's type not matching its expected spec) -- likely
    # a partially illegible page.
    EXTRACTION_VALIDATION_FAILED = "extraction_validation_failed"

    UNKNOWN = "unknown"


class OcrError(Exception):
    """Raised for any OCR failure, carrying a stable `code` callers can branch on."""

    def __init__(self, code: OcrFailureCode, message: str):
        self.code = code
        self.message = message
        super().__init__(message)
