"""Fail-fast guards and pre-write gate for day-mode invariant."""

from __future__ import annotations

import logging

logger = logging.getLogger(__name__)

DAY_MS = 86_400_000  # milliseconds per UTC day


def split_trades_by_day(trades: list[dict]) -> list[list[dict]]:
    """Split a trade list into per-UTC-day groups for Ouroboros day-mode.

    Each group contains trades from exactly one UTC day.
    Trades must be sorted chronologically.
    """
    if not trades:
        return []
    groups: list[list[dict]] = [[]]
    current_day = -1
    for t in trades:
        ts_ms = t.get("timestamp") or t.get("time", 0)
        day = ts_ms // DAY_MS
        if current_day == -1:
            current_day = day
        if day != current_day:
            groups.append([])
            current_day = day
        groups[-1].append(t)
    # Fail-fast assertion: each group is single-day
    for g in groups:
        if g:
            first_day = (g[0].get("timestamp") or g[0].get("time", 0)) // DAY_MS
            last_day = (g[-1].get("timestamp") or g[-1].get("time", 0)) // DAY_MS
            assert first_day == last_day, (
                f"Day-mode invariant violated: group spans days {first_day} -> {last_day}"
            )
    return groups


def validate_bar_day_mode(bar: dict, *, strict: bool = True) -> bool:
    """Validate a single bar does not span UTC midnight.

    Args:
        bar: Bar dict with open_time_ms and close_time_ms keys.
        strict: If True, raise AssertionError on violation. If False, return False.

    Returns:
        True if bar is within a single UTC day.
    """
    open_ms = bar.get("open_time_ms", 0)
    close_ms = bar.get("close_time_ms", 0)
    open_day = open_ms // DAY_MS
    close_day = close_ms // DAY_MS
    if open_day != close_day:
        msg = (
            f"Cross-midnight bar: open_time_ms={open_ms} (day {open_day}) "
            f"close_time_ms={close_ms} (day {close_day})"
        )
        if strict:
            raise AssertionError(msg)
        logger.error(msg)
        return False
    return True


def validate_bars_day_mode(bars: list[dict], *, strict: bool = True) -> int:
    """Validate a batch of bars for day-mode compliance.

    Args:
        bars: List of bar dicts.
        strict: If True, raise on first violation. If False, count violations.

    Returns:
        Number of violations (0 = all clean).
    """
    violations = 0
    for bar in bars:
        if not validate_bar_day_mode(bar, strict=strict):
            violations += 1
    return violations
