"""Node sharing controls for Hive Mode.

Determines whether a member can share a given model at a given time based on
sharing_enabled, sharing_schedule (daily window), and shared_models whitelist.
"""

from __future__ import annotations

import re
from datetime import datetime, timezone
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from llmhosts.hive.models import HiveMember

# "HH:MM-HH:MM" or "H:MM-HH:MM" daily window
_SCHEDULE_RE = re.compile(r"^(\d{1,2}):(\d{2})-(\d{1,2}):(\d{2})$")


def _parse_schedule(schedule: str) -> tuple[int, int, int, int] | None:
    """Parse 'HH:MM-HH:MM' into (start_h, start_m, end_h, end_m). Returns None if invalid."""
    m = _SCHEDULE_RE.match(schedule.strip())
    if not m:
        return None
    sh, sm, eh, em = int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4))
    if not (0 <= sh <= 23 and 0 <= sm <= 59 and 0 <= eh <= 23 and 0 <= em <= 59):
        return None
    return (sh, sm, eh, em)


def _in_schedule_window(schedule: str, now: datetime) -> bool:
    """Return True if now falls within the daily window (handles overnight e.g. 22:00-08:00)."""
    parsed = _parse_schedule(schedule)
    if parsed is None:
        return True  # Invalid schedule: treat as always in window
    sh, sm, eh, em = parsed
    start_mins = sh * 60 + sm
    end_mins = eh * 60 + em
    now_mins = now.hour * 60 + now.minute
    if start_mins <= end_mins:
        return start_mins <= now_mins <= end_mins
    # Overnight: e.g. 22:00-08:00 means 22:00..24:00 or 0:00..08:00
    return now_mins >= start_mins or now_mins <= end_mins


def can_share_model(member: HiveMember, model_name: str, *, now: datetime | None = None) -> bool:
    """Return True if this member can share the given model at the given time.

    Respects:
    - sharing_enabled: if False, never share
    - sharing_schedule: if set (e.g. "22:00-08:00"), only share when current time is in window
    - shared_models: if non-empty, only share models in the list; if empty, all models shareable

    SENSITIVE-tier requests are never routed to Hive (enforced by the main router/dispatcher).
    """
    if not member.sharing_enabled:
        return False
    if member.sharing_schedule:
        t = now or datetime.now(timezone.utc)
        if not _in_schedule_window(member.sharing_schedule, t):
            return False
    # Whitelist: if non-empty, model must be in list (exact match; optional tag handling)
    return not member.shared_models or model_name in member.shared_models
