import asyncio

import pytest

from nanobot.heartbeat.service import HeartbeatService


@pytest.mark.asyncio
async def test_start_is_idempotent(tmp_path) -> None:
    service = HeartbeatService(
        workspace=tmp_path,
        interval_s=9999,
        enabled=True,
    )

    await service.start()
    first_task = service._task
    await service.start()

    assert service._task is first_task

    service.stop()
    await asyncio.sleep(0)


@pytest.mark.asyncio
async def test_trigger_now_executes_when_decision_is_run(tmp_path) -> None:
    (tmp_path / "HEARTBEAT.md").write_text("- [ ] do thing", encoding="utf-8")

    called_with: list[tuple[str, dict | None]] = []

    async def _on_heartbeat(prompt: str, metadata: dict | None = None) -> str:
        called_with.append((prompt, metadata))
        return "done"

    service = HeartbeatService(
        workspace=tmp_path,
        on_heartbeat=_on_heartbeat,
    )

    result = await service.trigger_now()
    assert result == "done"
    assert len(called_with) == 1
    prompt, metadata = called_with[0]
    assert "HEARTBEAT.md" in prompt
    assert metadata == {"suppress_output": True}


@pytest.mark.asyncio
async def test_trigger_now_returns_none_when_no_callback(tmp_path) -> None:
    (tmp_path / "HEARTBEAT.md").write_text("- [ ] do thing", encoding="utf-8")

    service = HeartbeatService(
        workspace=tmp_path,
        on_heartbeat=None,  # No callback
    )

    assert await service.trigger_now() is None
