import json
from collections.abc import Iterator
from typing import Any, cast

import pytest
from moto import mock_aws

from infrastructure.sqs_client import SqsClient
from tests.infrastructure import make_boto_client


@pytest.fixture
def sqs_setup() -> Iterator[tuple[SqsClient, Any, str]]:
    with mock_aws():
        boto_client = make_boto_client("sqs")
        queue: dict[str, Any] = boto_client.create_queue(QueueName="test-queue")
        queue_url = cast(str, queue["QueueUrl"])
        yield SqsClient(boto_client, queue_url), boto_client, queue_url


def test_send_returns_message_id(sqs_setup: tuple[SqsClient, Any, str]) -> None:
    # arrange
    client, _boto, _url = sqs_setup
    # act
    message_id = client.send({"hello": "world"})
    # assert
    assert isinstance(message_id, str)
    assert message_id


def test_send_json_serialises_body(sqs_setup: tuple[SqsClient, Any, str]) -> None:
    # arrange
    client, boto_client, queue_url = sqs_setup
    body = {"hello": "world", "count": 3}
    # act
    client.send(body)

    # assert
    received: dict[str, Any] = boto_client.receive_message(
        QueueUrl=queue_url, MaxNumberOfMessages=1
    )
    messages: list[dict[str, Any]] = received["Messages"]
    assert len(messages) == 1
    assert json.loads(messages[0]["Body"]) == body
