from __future__ import annotations

import threading
import time

import pytest

from firecrawl_client.queue import SemaphoreQueue


def test_semaphore_caps_concurrent_slots():
    """Capacity=2 → never more than 2 active threads in slot at once."""
    q = SemaphoreQueue(capacity=2)
    active = 0
    max_active = 0
    lock = threading.Lock()

    def worker():
        nonlocal active, max_active
        with q.slot():
            with lock:
                active += 1
                max_active = max(max_active, active)
            time.sleep(0.05)
            with lock:
                active -= 1

    threads = [threading.Thread(target=worker) for _ in range(5)]
    for t in threads:
        t.start()
    for t in threads:
        t.join()

    assert max_active == 2


def test_slot_releases_on_exception():
    """Slot must be released even when the with-block raises."""
    q = SemaphoreQueue(capacity=1)

    with pytest.raises(ValueError), q.slot():
        raise ValueError("boom")

    # If slot wasn't released, this would block forever — pytest timeout would catch it.
    with q.slot():
        pass


def test_default_capacity_is_3():
    q = SemaphoreQueue()
    assert q.capacity == 3
