# app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_parser.py

from __future__ import annotations

import pytest

from src.market_data.acquisition.adapters.dzengi.parser import parse_candles
from src.market_data.acquisition.exceptions import CandleParseError
from src.market_data.acquisition.validation.schema import (
    validate_candles_schema,
)


def test_parse_candles_parses_object_item() -> None:
    document = validate_candles_schema(
        [
            {
                "openTime": 1000,
                "open": "100",
                "high": "110",
                "low": "90",
                "close": "105",
                "volume": "12.5",
            }
        ]
    )

    result = parse_candles(document)

    assert len(result.items) == 1
    item = result.items[0]
    assert item.open_time == 1000
    assert item.open_price == "100"
    assert item.high_price == "110"
    assert item.low_price == "90"
    assert item.close_price == "105"
    assert item.volume == "12.5"


@pytest.mark.parametrize(
    "time_key",
    ["openTime", "open_time", "time", "timestamp"],
)
def test_parse_candles_supports_time_aliases(time_key: str) -> None:
    document = validate_candles_schema(
        [
            {
                time_key: 1000,
                "open": "100",
                "high": "110",
                "low": "90",
                "close": "105",
                "volume": "12.5",
            }
        ]
    )

    result = parse_candles(document)

    assert result.items[0].open_time == 1000


def test_parse_candles_parses_array_item() -> None:
    document = validate_candles_schema(
        [[1000, "100", "110", "90", "105", "12.5", "ignored"]]
    )

    result = parse_candles(document)

    item = result.items[0]
    assert item.open_time == 1000
    assert item.open_price == "100"
    assert item.high_price == "110"
    assert item.low_price == "90"
    assert item.close_price == "105"
    assert item.volume == "12.5"


def test_parse_candles_accepts_empty_document() -> None:
    result = parse_candles(validate_candles_schema([]))

    assert result.items == ()


def test_parse_candles_rejects_missing_required_field() -> None:
    document = validate_candles_schema(
        [
            {
                "openTime": 1000,
                "open": "100",
                "high": "110",
                "low": "90",
                "volume": "12.5",
            }
        ]
    )

    with pytest.raises(CandleParseError, match="close"):
        parse_candles(document)


@pytest.mark.parametrize(
    "invalid_time",
    [True, 1.5, "1000", None],
)
def test_parse_candles_rejects_invalid_open_time(
    invalid_time: object,
) -> None:
    document = validate_candles_schema(
        [[invalid_time, "100", "110", "90", "105", "12.5"]]
    )

    with pytest.raises(
        CandleParseError,
        match=r"\$\.candles\[0\]\[0\]",
    ):
        parse_candles(document)


@pytest.mark.parametrize(
    "invalid_value",
    [True, None, {}, []],
)
def test_parse_candles_rejects_invalid_numeric_transport_value(
    invalid_value: object,
) -> None:
    document = validate_candles_schema(
        [[1000, invalid_value, "110", "90", "105", "12.5"]]
    )

    with pytest.raises(
        CandleParseError,
        match=r"\$\.candles\[0\]\[1\]",
    ):
        parse_candles(document)
