"""E2E tests for day-mode ouroboros populate path.

Migrated from monthly ouroboros tests (Issue #134 Phase 4) to day-only mode.

Tests cover (without requiring ClickHouse):
- Checkpoint path includes ouroboros mode suffix
- Day boundary detection
- Checkpoint mode mismatch raises ValueError
- CacheKey hash consistency
"""

from __future__ import annotations

from pathlib import Path

import pytest
from opendeviationbar.checkpoint import (
    PopulationCheckpoint,
    _get_checkpoint_path,
    _is_ouroboros_boundary,
)
from opendeviationbar.clickhouse.cache import CacheKey


class TestCheckpointPathSuffix:
    """Verify checkpoint path includes _{ouroboros_mode}.json suffix."""

    def test_day_suffix(self, tmp_path: Path):
        path = _get_checkpoint_path(
            "BTCUSDT", 250, "2024-01-01", "2024-12-31",
            checkpoint_dir=tmp_path, ouroboros_mode="day",
        )
        assert path.name == "BTCUSDT_250_2024-01-01_2024-12-31_day.json"


class TestDayBoundaryDetection:
    """Verify _is_ouroboros_boundary fires on every day in day mode."""

    @pytest.mark.parametrize("day", [1, 5, 10, 15, 20, 28])
    def test_every_day_is_boundary(self, day: int):
        assert _is_ouroboros_boundary(f"2024-06-{day:02d}", "day") is True

    def test_legacy_modes_rejected(self):
        """Legacy modes raise ValueError."""
        for mode in ("year", "month", "week"):
            with pytest.raises(ValueError, match="Only 'day' mode is supported"):
                _is_ouroboros_boundary("2024-01-01", mode)


class TestCheckpointModeMismatch:
    """Verify that resuming with a different ouroboros_mode raises ValueError."""

    def _make_checkpoint(self, *, ouroboros_mode: str = "day") -> PopulationCheckpoint:
        return PopulationCheckpoint(
            symbol="BTCUSDT",
            threshold_bps=250,
            start_date="2024-01-01",
            end_date="2024-12-31",
            last_completed_date="2024-03-15",
            bars_written=1000,
            ouroboros_mode=ouroboros_mode,
        )

    def test_matching_mode_no_error(self):
        """Same mode in checkpoint and current config → no error."""
        ckpt = self._make_checkpoint(ouroboros_mode="day")
        assert ckpt.ouroboros_mode == "day"


class TestCacheKeyHashConsistency:
    """Verify CacheKey hash is consistent for day mode."""

    def test_same_mode_same_hash(self):
        """Identical params + same ouroboros_mode → identical hash_key."""
        key_a = CacheKey(
            symbol="BTCUSDT",
            threshold_decimal_bps=250,
            start_ts=1704067200000,
            end_ts=1735689600000,
            ouroboros_mode="day",
        )
        key_b = CacheKey(
            symbol="BTCUSDT",
            threshold_decimal_bps=250,
            start_ts=1704067200000,
            end_ts=1735689600000,
            ouroboros_mode="day",
        )
        assert key_a.hash_key == key_b.hash_key

    def test_different_ouroboros_different_hash(self):
        """Different ouroboros_mode string produces different hash."""
        key_day = CacheKey(
            symbol="BTCUSDT",
            threshold_decimal_bps=250,
            start_ts=1704067200000,
            end_ts=1735689600000,
            ouroboros_mode="day",
        )
        key_other = CacheKey(
            symbol="BTCUSDT",
            threshold_decimal_bps=250,
            start_ts=1704067200000,
            end_ts=1735689600000,
            ouroboros_mode="other",
        )
        assert key_day.hash_key != key_other.hash_key
