"""One-shot backfill of `usage_marketplace_item_daily` + `_window` from existing usage_events.

After v45→v46 migrates the schema, the new rollup tables start empty. The
UsageProcessor rebuilds them on its first tick (7-day incremental for daily
fact + 7d window) and within an hour fills `last_30d`, so doing nothing is
also a valid path — but the marketplace pages then show zero invocations
for up to 30 days until events older than the 7-day incremental window
flow back into the rollup.

This script forces a full rebuild from `usage_events` immediately. Safe
to re-run — uses the same `rebuild_rollups()` function the scheduler
invokes, which is idempotent (DELETE+INSERT).

Usage::

    python scripts/backfill_marketplace_rollup.py
"""
from __future__ import annotations

import logging
import sys
from datetime import datetime, timezone

from services.session_processors.usage_lib import rebuild_rollups
from src.db import get_system_db

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
log = logging.getLogger(__name__)


def main() -> int:
    conn = get_system_db()

    # Find the oldest usage_event so the daily-fact rebuild covers all
    # historical data, not just the default 7-day incremental window.
    row = conn.execute(
        "SELECT MIN(CAST(occurred_at AS DATE)) FROM usage_events"
    ).fetchone()
    since_day = row[0] if row and row[0] else datetime.now(timezone.utc).date()

    log.info("backfill_marketplace_rollup: since_day=%s, force_30d=True", since_day)
    rebuild_rollups(conn, since_day=since_day, force_30d=True)

    daily_rows = conn.execute(
        "SELECT COUNT(*) FROM usage_marketplace_item_daily"
    ).fetchone()[0]
    window_rows = conn.execute(
        "SELECT period_label, COUNT(*) FROM usage_marketplace_item_window GROUP BY 1"
    ).fetchall()
    log.info(
        "backfill complete: daily=%d window=%s",
        daily_rows, dict(window_rows),
    )
    return 0


if __name__ == "__main__":
    sys.exit(main())
