"""Tests for ApiHookClient.get_io_pool_status and wait_io_pool_idle.

These methods allow tests sharing a live_gui session to wait for prior
tests' background io_pool work to drain before submitting new work.

ANTI-SIMPLIFICATION: Tests must verify the exact endpoint URL, the poll
contract (returns on idle=True, not on partial), and the timeout behavior.
"""
import pytest
from unittest.mock import patch
import sys
import os

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))

from src.api_hook_client import ApiHookClient


def test_get_io_pool_status_calls_endpoint() -> None:
 """get_io_pool_status hits GET /api/io_pool_status and returns the dict."""
 client = ApiHookClient()
 with patch.object(client, "_make_request") as mock_make:
  mock_make.return_value = {"idle": True, "inflight": 0}
  status = client.get_io_pool_status()
  assert status == {"idle": True, "inflight": 0}
  mock_make.assert_any_call("GET", "/api/io_pool_status")


def test_get_io_pool_status_handles_empty_response() -> None:
 """get_io_pool_status returns {idle: True, inflight: 0} on empty/invalid."""
 client = ApiHookClient()
 with patch.object(client, "_make_request") as mock_make:
  mock_make.return_value = None
  status = client.get_io_pool_status()
  assert status == {"idle": True, "inflight": 0}


def test_wait_io_pool_idle_returns_immediately_when_idle() -> None:
 """wait_io_pool_idle returns True on first poll if already idle."""
 client = ApiHookClient()
 with patch.object(client, "get_io_pool_status") as mock_status:
  mock_status.return_value = {"idle": True, "inflight": 0}
  result = client.wait_io_pool_idle(timeout=5.0)
  assert result is True
  assert mock_status.call_count == 1


def test_wait_io_pool_idle_polls_then_returns_when_idle() -> None:
 """wait_io_pool_idle polls multiple times until idle, then returns True."""
 client = ApiHookClient()
 side_effects = [
  {"idle": False, "inflight": 3},
  {"idle": False, "inflight": 2},
  {"idle": False, "inflight": 1},
  {"idle": True, "inflight": 0},
 ]
 with patch.object(client, "get_io_pool_status") as mock_status:
  mock_status.side_effect = side_effects
  with patch("time.sleep") as mock_sleep:
   result = client.wait_io_pool_idle(timeout=10.0, poll_interval=0.1)
  assert result is True
  assert mock_status.call_count == 4
  assert mock_sleep.call_count == 3


def test_wait_io_pool_idle_times_out_when_never_idle() -> None:
 """wait_io_pool_idle returns False if pool never becomes idle."""
 client = ApiHookClient()
 with patch.object(client, "get_io_pool_status") as mock_status:
  mock_status.return_value = {"idle": False, "inflight": 5}
  with patch("time.time") as mock_time:
   # Simulate time progressing past the timeout
   mock_time.side_effect = [0.0, 0.1, 0.2, 0.3, 100.0, 100.1]
   with patch("time.sleep") as mock_sleep:
    result = client.wait_io_pool_idle(timeout=5.0, poll_interval=0.1)
  assert result is False
