"""Tests for yier_cli background follow-up helpers."""

from pathlib import Path
import sys
from uuid import uuid4

import pytest

from yier_agents.src.tools import BackgroundCommandManager
from yier_agents.src.tool import ToolContext
from yier_agents.yier_cli import (
    ChatUIState,
    FollowupQueueManager,
    consume_pending_context_notes,
    create_queue_background_followup_tool,
    sync_background_updates,
)


def test_followup_queue_manager_releases_ready_items_in_order():
    """Queued follow-ups should release in insertion order for matching sessions."""
    queue = FollowupQueueManager()
    first = queue.add("bg-1", "summarize result", source="user")
    queue.add("bg-2", "ignore for now", source="agent")
    third = queue.add("bg-1", "continue the next task", source="agent")

    ready = queue.pop_ready({"bg-1"})

    assert [item.queue_id for item in ready] == [first.queue_id, third.queue_id]
    assert queue.count() == 1
    assert queue.list_items()[0].trigger_session_id == "bg-2"


def test_consume_pending_context_notes_wraps_prompt_and_clears_state():
    """Pending background notes should be injected once into the next prompt."""
    ui_state = ChatUIState(
        session_id=str(uuid4()),
        skill_names=(),
        pending_context_notes=["first note", "second note"],
    )

    prompt = consume_pending_context_notes(ui_state, "Please continue")

    assert "<background_updates>" in prompt
    assert "first note" in prompt
    assert "second note" in prompt
    assert "User request:\nPlease continue" in prompt
    assert ui_state.pending_context_notes == []


@pytest.mark.asyncio
async def test_sync_background_updates_collects_notes_and_releases_followups(tmp_path: Path):
    """Completed background commands should surface notes and ready queued tasks."""
    script_path = tmp_path / "done.py"
    script_path.write_text("print('done from bg')\n", encoding="utf-8")
    command = f'"{sys.executable}" "{script_path.name}"'

    manager = BackgroundCommandManager([tmp_path], default_root=tmp_path)
    session = await manager.start(command, cwd=str(tmp_path))
    await manager.wait(session.session_id, timeout_seconds=2)

    queue = FollowupQueueManager()
    queued = queue.add(session.session_id, "summarize the result", source="user")
    ui_state = ChatUIState(session_id=str(uuid4()), skill_names=())

    ready = sync_background_updates(manager, queue, ui_state)

    assert [item.queue_id for item in ready] == [queued.queue_id]
    assert ui_state.background_count == 0
    assert ui_state.queued_count == 0
    assert len(ui_state.pending_context_notes) == 1
    assert session.session_id in ui_state.pending_context_notes[0]
    assert "done from bg" in ui_state.pending_context_notes[0]


@pytest.mark.asyncio
async def test_queue_background_followup_tool_returns_structured_payload(tmp_path: Path):
    """Queue tool should expose structured metadata and raw payload for UI use."""
    script_path = tmp_path / "wait.py"
    script_path.write_text("import time; time.sleep(1)\n", encoding="utf-8")
    command = f'"{sys.executable}" "{script_path.name}"'

    manager = BackgroundCommandManager([tmp_path], default_root=tmp_path)
    session = await manager.start(command, cwd=str(tmp_path))
    queue = FollowupQueueManager()
    tool = create_queue_background_followup_tool(manager, queue)
    ctx = ToolContext(session_id="s1", message_id="m1", call_id="c1")

    result = await tool.execute(
        tool.parameters(session_id=session.session_id, prompt="summarize it"),
        ctx,
    )

    assert result.metadata["queue_id"].startswith("q-")
    assert result.raw["kind"] == "queued_followup"
    assert result.raw["queued"] is True
    assert result.raw["session_id"] == session.session_id

    await manager.stop(session.session_id)
