"""Tests for resilience utilities — connectivity, DB integrity, timeouts."""

from __future__ import annotations

import asyncio
import sqlite3

import pytest

from agent_scout.resilience import (
    TaskTimeout,
    attempt_db_recovery,
    check_db_integrity,
)


@pytest.mark.asyncio
async def test_db_integrity_check_on_valid_db(tmp_path):
    db_path = str(tmp_path / "test.db")
    conn = sqlite3.connect(db_path)
    conn.execute("CREATE TABLE t (id INTEGER PRIMARY KEY)")
    conn.close()

    result = await check_db_integrity(db_path)
    assert result["ok"] is True
    assert result["message"] == "ok"


@pytest.mark.asyncio
async def test_db_integrity_check_missing_file(tmp_path):
    result = await check_db_integrity(str(tmp_path / "missing.db"))
    assert result["ok"] is False
    assert "does not exist" in result["message"]


@pytest.mark.asyncio
async def test_db_integrity_check_corrupted_file(tmp_path):
    db_path = tmp_path / "corrupt.db"
    db_path.write_bytes(b"this is not a valid sqlite file at all!!!")

    result = await check_db_integrity(str(db_path))
    assert result["ok"] is False


@pytest.mark.asyncio
async def test_db_recovery_missing_file(tmp_path):
    result = await attempt_db_recovery(str(tmp_path / "nonexistent.db"))
    assert result is False


@pytest.mark.asyncio
async def test_db_recovery_on_valid_db(tmp_path):
    db_path = str(tmp_path / "test.db")
    conn = sqlite3.connect(db_path)
    conn.execute("CREATE TABLE t (id INTEGER PRIMARY KEY, name TEXT)")
    conn.execute("INSERT INTO t VALUES (1, 'hello')")
    conn.commit()
    conn.close()

    result = await attempt_db_recovery(db_path)
    assert result is True

    # Verify data survived
    conn = sqlite3.connect(db_path)
    row = conn.execute("SELECT name FROM t WHERE id = 1").fetchone()
    conn.close()
    assert row[0] == "hello"


@pytest.mark.asyncio
async def test_task_timeout_properties():
    async with TaskTimeout(seconds=60.0) as timer:
        assert timer.remaining > 0
        assert timer.remaining <= 60.0
        assert not timer.expired


@pytest.mark.asyncio
async def test_task_timeout_expiration():
    async with TaskTimeout(seconds=0.01) as timer:
        await asyncio.sleep(0.02)
        assert timer.expired
        assert timer.remaining == 0.0


@pytest.mark.asyncio
async def test_task_timeout_remaining_before_entry():
    timer = TaskTimeout(seconds=100.0)
    assert timer.remaining == 100.0
