"""Shared epoch-day date-axis helpers for the paper-snapshot runners.

A "panel" addresses days as integer epoch days (days since 1970-01-01). `as_of` strings come in two
forms — `epoch:<int>` (raw epoch day) or an ISO date (`YYYY-MM-DD`) — and resolve to the same axis.
Hoisted here so `stablecoin_runner`, `unlock_runner`, and `ts_trend_strategy` share one definition.
"""
from __future__ import annotations

import datetime as dt

EPOCH = dt.date(1970, 1, 1)


def iso(epoch_day: int) -> str:
    """Epoch day -> ISO date string."""
    return (EPOCH + dt.timedelta(days=int(epoch_day))).isoformat()


def as_of_day(as_of: str) -> int:
    """Resolve an `as_of` rebalance date to an epoch day. Accepts `epoch:<int>` or an ISO date."""
    if as_of.startswith("epoch:"):
        return int(as_of.split(":", 1)[1])
    return (dt.date.fromisoformat(as_of) - EPOCH).days
