# app/tests/unit/market_data/acquisition/models/test_status.py

from __future__ import annotations

from dataclasses import FrozenInstanceError

import pytest

from src.market_data.acquisition.models.status import (
    InstrumentStatusClassification,
    InstrumentTradingState,
    classify_instrument_status,
)


@pytest.mark.parametrize(
    "raw_status",
    [
        "TRADING",
        "OPEN",
        "ACTIVE",
        "ENABLED",
        "ONLINE",
    ],
)
def test_classify_open_statuses(raw_status: str) -> None:
    result = classify_instrument_status(raw_status)

    assert result == InstrumentStatusClassification(
        state=InstrumentTradingState.OPEN,
        normalized_status=raw_status,
    )


@pytest.mark.parametrize(
    "raw_status",
    [
        "NOT_TRADABLE",
        "TRADING_DISABLED",
        "MARKET_DISABLED",
        "UNAVAILABLE_FOR_TRADING",
        "CLOSE_ONLY",
        "REDUCE_ONLY",
        "VIEW_ONLY",
    ],
)
def test_classify_not_tradable_statuses(raw_status: str) -> None:
    result = classify_instrument_status(raw_status)

    assert result == InstrumentStatusClassification(
        state=InstrumentTradingState.NOT_TRADABLE,
        normalized_status=raw_status,
    )


@pytest.mark.parametrize(
    "raw_status",
    [
        "BREAK",
        "CLOSED",
        "HALT",
        "HALTED",
        "PAUSED",
        "SUSPENDED",
        "DISABLED",
        "SETTLING",
        "POST_ONLY",
    ],
)
def test_classify_break_statuses(raw_status: str) -> None:
    result = classify_instrument_status(raw_status)

    assert result == InstrumentStatusClassification(
        state=InstrumentTradingState.BREAK,
        normalized_status=raw_status,
    )


def test_classification_normalizes_case_and_outer_spaces() -> None:
    result = classify_instrument_status(
        "  trading  "
    )

    assert result == InstrumentStatusClassification(
        state=InstrumentTradingState.OPEN,
        normalized_status="TRADING",
    )


@pytest.mark.parametrize(
    "raw_status",
    [
        None,
        "",
        " ",
        "   ",
    ],
)
def test_empty_status_is_unknown(
    raw_status: str | None,
) -> None:
    result = classify_instrument_status(raw_status)

    assert result == InstrumentStatusClassification(
        state=InstrumentTradingState.UNKNOWN,
        normalized_status=None,
    )


def test_unknown_status_preserves_normalized_value() -> None:
    result = classify_instrument_status(
        "  maintenance  "
    )

    assert result == InstrumentStatusClassification(
        state=InstrumentTradingState.UNKNOWN,
        normalized_status="MAINTENANCE",
    )


def test_classification_result_is_frozen() -> None:
    result = classify_instrument_status(
        "TRADING"
    )

    with pytest.raises(FrozenInstanceError):
        result.normalized_status = "BREAK"  # type: ignore[misc]