"""Checkpoint management for interrupt recovery (S2-R1-022)."""

from __future__ import annotations

import hashlib
import json
from datetime import datetime, timezone
from pathlib import Path

from loguru import logger



def _config_hash(config: dict) -> str:
    """Deterministic hash of config for change detection."""
    serialized = json.dumps(config, sort_keys=True, default=str)
    return hashlib.sha256(serialized.encode()).hexdigest()[:16]


class CheckpointManager:
    FILENAME = "progress.json"

    def __init__(self, tmp_dir: str, config: dict) -> None:
        self.path = Path(tmp_dir) / self.FILENAME
        self.config = config
        self._hash = _config_hash(config)

    def load(self) -> dict | None:
        """Load existing checkpoint. Returns None if no valid checkpoint."""
        if not self.path.exists():
            return None

        try:
            data = json.loads(self.path.read_text())
        except (json.JSONDecodeError, OSError):
            logger.warning("Corrupt checkpoint file, starting fresh")
            return None

        if data.get("config_hash") != self._hash:
            logger.info("Config changed since last run, starting fresh")
            self.clear()
            return None

        logger.info(
            f"Resuming: pass={data['current_pass']}, "
            f"completed={len(data['completed_chunks'])}/{data['total_chunks']} chunks"
        )
        return data

    def save(self, current_pass: int, completed_chunks: list[int], total_chunks: int) -> None:
        """Save checkpoint state."""
        state = {
            "video_path": str(self.config.get("video_path", "")),
            "config_hash": self._hash,
            "current_pass": current_pass,
            "completed_chunks": completed_chunks,
            "total_chunks": total_chunks,
            "timestamp": datetime.now(timezone.utc).isoformat(),
        }
        self.path.write_text(json.dumps(state, indent=2))

    def clear(self) -> None:
        """Remove checkpoint file."""
        if self.path.exists():
            self.path.unlink()

    def is_chunk_done(self, checkpoint: dict | None, pass_num: int, chunk_id: int) -> bool:
        """Check if a specific chunk was already completed."""
        if checkpoint is None:
            return False
        if checkpoint.get("current_pass", 0) > pass_num:
            return True
        if checkpoint.get("current_pass", 0) == pass_num:
            return chunk_id in checkpoint.get("completed_chunks", [])
        return False
