import time
from threading import Thread

from assertpy import assert_that
from messagebus import (
    AckMessage,
    Message,
    MessageBusException,
)


def test_receives_a_sent_message(
    sender_message_bus,
    receiver_message_bus,
    receiver_address,
):
    sent_message = AckMessage()

    def send_message():
        sender_message_bus.send_direct_message(
            address=receiver_address,
            message=sent_message,
        )

    t = Thread(target=send_message)
    t.start()

    received_message = receiver_message_bus.receive()
    receiver_message_bus.reply_message(
        message=received_message,
        reply_message=AckMessage(),
    )

    assert_that(sent_message).is_equal_to(received_message)

    t.join()


def test_blocks_until_a_message_is_received(
    sender_message_bus,
    receiver_message_bus,
    receiver_address,
):
    message_sent = False

    def send_message():
        nonlocal message_sent

        message_sent = True
        sender_message_bus.send_direct_message(
            address=receiver_address,
            message=Message(
                token=1,
                timeout=1,
            ),
        )

    Thread(target=send_message).start()

    receiver_message_bus.receive()

    assert_that(message_sent).is_true()


def test_returns_None_if_a_timeout_is_specified_and_no_message_is_received(
    receiver_message_bus,
):
    received = receiver_message_bus.receive(timeout=0.01)

    assert_that(received).is_none()
