"""Tests for agent progress tracking (Phase 7, Stream E)."""

import pytest
from datetime import datetime, timezone

from loom.bus.channels import task_progress_key
from loom.graph.cache import set_task_progress, get_task_progress


class TestTaskProgressKey:
    def test_key_format(self):
        key = task_progress_key("proj-1", "task-1")
        assert key == "loom:proj-1:task:task-1:progress"


class TestSetTaskProgress:
    @pytest.mark.asyncio
    async def test_set_progress_message(self, redis_conn):
        """Setting progress should store message in Redis."""
        await set_task_progress(redis_conn, "proj-1", "task-1", progress="Running tests")
        data = await redis_conn.hgetall(task_progress_key("proj-1", "task-1"))
        assert data["message"] == "Running tests"
        assert data["updated_at"]  # should be set

    @pytest.mark.asyncio
    async def test_set_progress_percent(self, redis_conn):
        """Setting progress with percent should store both."""
        await set_task_progress(redis_conn, "proj-1", "task-1", progress="50% done", percent=50)
        data = await redis_conn.hgetall(task_progress_key("proj-1", "task-1"))
        assert data["message"] == "50% done"
        assert data["percent"] == "50"

    @pytest.mark.asyncio
    async def test_progress_has_expiry(self, redis_conn):
        """Progress key should have TTL set."""
        await set_task_progress(redis_conn, "proj-1", "task-1", progress="working")
        ttl = await redis_conn.ttl(task_progress_key("proj-1", "task-1"))
        assert ttl > 0  # should have TTL


class TestGetTaskProgress:
    @pytest.mark.asyncio
    async def test_get_existing_progress(self, redis_conn):
        """Should return progress data when it exists."""
        await set_task_progress(redis_conn, "proj-1", "task-1", progress="Building", percent=75)
        result = await get_task_progress(redis_conn, "proj-1", "task-1")
        assert result is not None
        assert result["message"] == "Building"
        assert result["percent"] == 75
        assert result["updated_at"]

    @pytest.mark.asyncio
    async def test_get_nonexistent_progress(self, redis_conn):
        """Should return None for tasks with no progress."""
        result = await get_task_progress(redis_conn, "proj-1", "nonexistent")
        assert result is None

    @pytest.mark.asyncio
    async def test_get_progress_no_percent(self, redis_conn):
        """Progress without percent should return None for percent field."""
        await set_task_progress(redis_conn, "proj-1", "task-1", progress="Working")
        result = await get_task_progress(redis_conn, "proj-1", "task-1")
        assert result is not None
        assert result["percent"] is None
        assert result["message"] == "Working"
