"""Tests for IndicatorSpec display_name generation."""

from tradepose_models.enums import Freq
from tradepose_models.strategy.indicator_spec import IndicatorSpec


class TestRawOhlcvDisplayName:
    """測試 RawOhlcv 指標的 display_name 生成（應與 Rust 一致）"""

    def test_raw_ohlcv_without_instrument(self):
        """無 instrument 時的格式：{column}_{freq}"""
        spec = IndicatorSpec(
            instrument=None,
            instrument_id=0,
            freq=Freq.DAY_1,
            shift=1,
            indicator={"type": "RawOhlcv", "column": "open"},
        )
        assert spec.display_name() == "open_1D"

    def test_raw_ohlcv_with_instrument(self):
        """有 instrument 時的格式：{instrument}_{column}_{freq}"""
        spec = IndicatorSpec(
            instrument="FTMO:swap:XAUUSD",
            instrument_id=1,
            freq=Freq.HOUR_4,
            shift=1,
            indicator={"type": "RawOhlcv", "column": "low"},
        )
        # 應該是 {instrument}_{column}_{freq}，不是 {instrument}_{freq}_{column}
        assert spec.display_name() == "FTMO:swap:XAUUSD_low_4h"

    def test_raw_ohlcv_with_shift(self):
        """shift != 1 時應該加上 _s{shift} 後綴"""
        spec = IndicatorSpec(
            instrument=None,
            instrument_id=0,
            freq=Freq.MIN_30,
            shift=2,
            indicator={"type": "RawOhlcv", "column": "high"},
        )
        assert spec.display_name() == "high_30min_s2"

    def test_raw_ohlcv_all_columns(self):
        """測試所有 OHLCV 欄位"""
        for column in ["open", "high", "low", "close", "volume"]:
            spec = IndicatorSpec(
                instrument="ES",
                instrument_id=1,
                freq=Freq.DAY_1,
                shift=1,
                indicator={"type": "RawOhlcv", "column": column},
            )
            assert spec.display_name() == f"ES_{column}_1D"


class TestGeneralIndicatorDisplayName:
    """測試一般指標的 display_name 生成（確保未受影響）"""

    def test_sma_without_instrument(self):
        """SMA 無 instrument 時的格式：{freq}_{short_name}"""
        spec = IndicatorSpec(
            instrument=None,
            instrument_id=0,
            freq=Freq.MIN_1,
            shift=1,
            indicator={"type": "SMA", "period": 20, "column": "close"},
        )
        assert spec.display_name() == "1min_SMA|20.close"

    def test_sma_with_instrument(self):
        """SMA 有 instrument 時的格式：{instrument}_{freq}_{short_name}"""
        spec = IndicatorSpec(
            instrument="ES",
            instrument_id=1,
            freq=Freq.MIN_1,
            shift=1,
            indicator={"type": "SMA", "period": 20, "column": "close"},
        )
        assert spec.display_name() == "ES_1min_SMA|20.close"

    def test_atr_with_shift(self):
        """ATR shift != 1 時應該加上 _s{shift} 後綴"""
        spec = IndicatorSpec(
            instrument=None,
            instrument_id=0,
            freq=Freq.DAY_1,
            shift=2,
            indicator={"type": "ATR", "period": 14},
        )
        assert spec.display_name() == "1D_ATR|14_s2"


class TestRustPythonConsistency:
    """確保 Python 和 Rust 的 display_name 格式一致"""

    def test_raw_ohlcv_format_matches_rust(self):
        """RawOhlcv 格式應該與 Rust 一致：{instrument}_{column}_{freq}"""
        # Rust 格式（來自 spec.rs:960-981）:
        # parts: [instrument, column, freq]
        # 結果: "FTMO:swap:XAUUSD_low_4h"
        spec = IndicatorSpec(
            instrument="FTMO:swap:XAUUSD",
            instrument_id=1,
            freq=Freq.HOUR_4,
            shift=1,
            indicator={"type": "RawOhlcv", "column": "low"},
        )
        # Python 應該產生相同的格式
        assert spec.display_name() == "FTMO:swap:XAUUSD_low_4h"

    def test_general_indicator_format_matches_rust(self):
        """一般指標格式應該與 Rust 一致：{instrument}_{freq}_{indicator_short_name}"""
        # Rust 格式（來自 spec.rs:983-1003）:
        # parts: [instrument, freq, indicator.short_name()]
        # 結果: "ES_1min_SMA|20.close"
        spec = IndicatorSpec(
            instrument="ES",
            instrument_id=1,
            freq=Freq.MIN_1,
            shift=1,
            indicator={"type": "SMA", "period": 20, "column": "close"},
        )
        # Python 應該產生相同的格式
        assert spec.display_name() == "ES_1min_SMA|20.close"
