"""Unit tests for file-based completion markers (no DB/Redis needed)."""

from __future__ import annotations

import json
from pathlib import Path

import pytest

from loom.markers import (
    archive_marker,
    read_markers,
    write_completion_marker,
    write_failure_marker,
)


@pytest.fixture()
def project_dir(tmp_path: Path) -> Path:
    """Create a minimal project directory with .loom/."""
    (tmp_path / ".loom").mkdir()
    return tmp_path


def test_write_completion_marker(project_dir: Path):
    path = write_completion_marker(
        project_dir, "loom-abc123",
        output={"summary": "Implemented feature X"},
        branch_name="feat/x",
        agent_id="agent-1",
    )
    assert path.exists()
    data = json.loads(path.read_text())
    assert data["task_id"] == "loom-abc123"
    assert data["status"] == "done"
    assert data["output"] == {"summary": "Implemented feature X"}
    assert data["branch_name"] == "feat/x"
    assert data["agent_id"] == "agent-1"
    assert "timestamp" in data


def test_write_failure_marker(project_dir: Path):
    path = write_failure_marker(
        project_dir, "loom-def456",
        reason="Tests failed with 3 errors",
        agent_id="agent-2",
    )
    assert path.exists()
    data = json.loads(path.read_text())
    assert data["task_id"] == "loom-def456"
    assert data["status"] == "failed"
    assert data["reason"] == "Tests failed with 3 errors"
    assert data["agent_id"] == "agent-2"


def test_write_completion_marker_defaults(project_dir: Path):
    """Minimal call — no output, branch, or agent."""
    path = write_completion_marker(project_dir, "loom-min001")
    data = json.loads(path.read_text())
    assert data["output"] == {}
    assert data["branch_name"] == ""
    assert data["agent_id"] == ""


def test_write_marker_creates_directory(project_dir: Path):
    """Completions directory is created on first write."""
    comp_dir = project_dir / ".loom" / "completions"
    assert not comp_dir.exists()
    write_completion_marker(project_dir, "loom-first1")
    assert comp_dir.is_dir()


def test_read_markers_empty(project_dir: Path):
    markers = read_markers(project_dir)
    assert markers == []


def test_read_markers_sorted_by_timestamp(project_dir: Path):
    write_completion_marker(project_dir, "loom-aaa001", output={"order": 1})
    write_failure_marker(project_dir, "loom-bbb002", reason="boom")
    write_completion_marker(project_dir, "loom-ccc003", output={"order": 3})

    markers = read_markers(project_dir)
    assert len(markers) == 3
    # Oldest first (monotonic timestamps)
    assert markers[0]["task_id"] == "loom-aaa001"
    assert markers[1]["task_id"] == "loom-bbb002"
    assert markers[2]["task_id"] == "loom-ccc003"
    # Each marker has a _path key
    for m in markers:
        assert "_path" in m


def test_read_markers_skips_corrupt_files(project_dir: Path):
    write_completion_marker(project_dir, "loom-good01")
    bad_path = project_dir / ".loom" / "completions" / "loom-bad.json"
    bad_path.write_text("not valid json{{{")

    markers = read_markers(project_dir)
    assert len(markers) == 1
    assert markers[0]["task_id"] == "loom-good01"


def test_archive_marker(project_dir: Path):
    path = write_completion_marker(project_dir, "loom-arc001")
    assert path.exists()

    archived = archive_marker(path)
    assert not path.exists()
    assert archived.exists()
    assert archived.parent.name == ".archive"

    # Archived file is valid JSON
    data = json.loads(archived.read_text())
    assert data["task_id"] == "loom-arc001"


def test_overwrite_existing_marker(project_dir: Path):
    """Writing a marker for the same task_id overwrites the previous one."""
    write_completion_marker(project_dir, "loom-dup001", output={"v": 1})
    write_completion_marker(project_dir, "loom-dup001", output={"v": 2})

    markers = read_markers(project_dir)
    assert len(markers) == 1
    assert markers[0]["output"] == {"v": 2}
