"""Helpers shared by Module 2 DAGs."""

from __future__ import annotations

import os
import pathlib
from datetime import timedelta


def transactional_write_path(final_path: pathlib.Path, run_id: str) -> pathlib.Path:
    """Build a per-run staging path that lives next to the final file.

    The staging path encodes the run_id so two concurrent runs (e.g., a
    backfill and a fresh schedule) writing the same hour don't collide.
    """
    safe_run = run_id.replace(":", "_").replace("+", "_")
    return final_path.with_suffix(f".staging.{safe_run}.parquet")


def atomic_replace(src: pathlib.Path, dst: pathlib.Path) -> None:
    """os.replace with explicit failure if src doesn't exist."""
    if not src.exists():
        raise FileNotFoundError(f"staging file missing: {src}")
    os.replace(src, dst)


# Retry policy preset for tasks that hit external APIs (gharchive).
EXTERNAL_API_RETRIES = dict(
    retries=3,
    retry_delay=timedelta(seconds=30),
    retry_exponential_backoff=True,
    max_retry_delay=timedelta(minutes=10),
)

# Pure-compute tasks shouldn't retry — failures are bugs.
PURE_COMPUTE_RETRIES = dict(retries=0)
