"""Tests for core/storage.py."""

import json
from pjctx.core.context import Context
from pjctx.core.storage import save_context, load_latest, list_contexts, list_branches


def test_save_and_load_latest(initialized_repo):
    ctx = Context(message="test save", branch="main", tags=["t1"])
    path = save_context(initialized_repo, ctx)

    assert path.exists()
    assert path.name.endswith(".json")

    loaded = load_latest(initialized_repo, "main")
    assert loaded is not None
    assert loaded.message == "test save"
    assert loaded.tags == ["t1"]


def test_latest_is_file_copy(initialized_repo):
    ctx = Context(message="copy test", branch="main")
    save_context(initialized_repo, ctx)

    latest = initialized_repo / ".pjctx" / "contexts" / "main" / "latest.json"
    assert latest.exists()
    assert not latest.is_symlink()

    data = json.loads(latest.read_text())
    assert data["message"] == "copy test"


def test_list_contexts(initialized_repo):
    for i in range(3):
        ctx = Context(message=f"msg {i}", branch="main")
        save_context(initialized_repo, ctx)

    contexts = list_contexts(initialized_repo, "main")
    assert len(contexts) == 3
    # Oldest first
    assert contexts[0].message == "msg 0"
    assert contexts[2].message == "msg 2"


def test_list_branches(initialized_repo):
    save_context(initialized_repo, Context(message="a", branch="main"))
    save_context(initialized_repo, Context(message="b", branch="feature/x"))

    branches = list_branches(initialized_repo)
    assert "main" in branches
    assert "feature/x" in branches


def test_nested_branch_dir(initialized_repo):
    ctx = Context(message="nested", branch="feature/deep/branch")
    path = save_context(initialized_repo, ctx)
    assert "feature/deep/branch" in str(path)

    loaded = load_latest(initialized_repo, "feature/deep/branch")
    assert loaded is not None
    assert loaded.message == "nested"


def test_load_latest_nonexistent(initialized_repo):
    result = load_latest(initialized_repo, "nonexistent")
    assert result is None
