"""File-based completion markers — pure filesystem fallback, no DB/Redis dependency.

Subagents write markers to `.loom/completions/` so the orchestrator can
recover their work even if it dies and loses context.
"""

from __future__ import annotations

import json
import shutil
from datetime import datetime, timezone
from pathlib import Path
from typing import Any


def _completions_dir(project_dir: str | Path) -> Path:
    return Path(project_dir) / ".loom" / "completions"


def write_completion_marker(
    project_dir: str | Path,
    task_id: str,
    output: dict[str, Any] | None = None,
    branch_name: str | None = None,
    agent_id: str | None = None,
) -> Path:
    """Write a completion marker for a finished task.

    Returns the path to the marker file.
    """
    marker = {
        "task_id": task_id,
        "status": "done",
        "output": output or {},
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "branch_name": branch_name or "",
        "agent_id": agent_id or "",
    }
    return _write_marker(project_dir, task_id, marker)


def write_failure_marker(
    project_dir: str | Path,
    task_id: str,
    reason: str,
    agent_id: str | None = None,
) -> Path:
    """Write a failure marker for a failed task.

    Returns the path to the marker file.
    """
    marker = {
        "task_id": task_id,
        "status": "failed",
        "reason": reason,
        "output": {},
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "branch_name": "",
        "agent_id": agent_id or "",
    }
    return _write_marker(project_dir, task_id, marker)


def _write_marker(project_dir: str | Path, task_id: str, marker: dict) -> Path:
    """Write a marker dict as JSON to the completions directory."""
    comp_dir = _completions_dir(project_dir)
    comp_dir.mkdir(parents=True, exist_ok=True)
    path = comp_dir / f"{task_id}.json"
    path.write_text(json.dumps(marker, indent=2) + "\n")
    return path


def read_markers(project_dir: str | Path) -> list[dict]:
    """Read all completion markers, sorted by timestamp (oldest first)."""
    comp_dir = _completions_dir(project_dir)
    if not comp_dir.is_dir():
        return []
    markers = []
    for path in comp_dir.glob("*.json"):
        try:
            data = json.loads(path.read_text())
            data["_path"] = str(path)
            markers.append(data)
        except (json.JSONDecodeError, OSError):
            continue
    markers.sort(key=lambda m: m.get("timestamp", ""))
    return markers


def archive_marker(marker_path: str | Path) -> Path:
    """Move a processed marker to the archive directory.

    Returns the new path in the archive.
    """
    marker_path = Path(marker_path)
    archive_dir = marker_path.parent / ".archive"
    archive_dir.mkdir(parents=True, exist_ok=True)
    dest = archive_dir / marker_path.name
    shutil.move(str(marker_path), str(dest))
    return dest
