import pytest

from src.utils import keyboard
from src.utils.ino import ArduinoUnavailableError


def _arduino(mocker):
    mocker.patch.object(keyboard, '_focusTibia')
    return mocker.patch.object(keyboard, 'sendCommandArduino', return_value=True)


def test_hotkey_uses_only_arduino_hid(mocker):
    send = _arduino(mocker)
    keyboard.hotkey('ctrl', 'a')
    assert send.call_args_list == [
        mocker.call('keyDown,128'), mocker.call('keyDown,97'),
        mocker.call('keyUp,97'), mocker.call('keyUp,128'),
    ]


def test_key_down_and_up_use_arduino(mocker):
    send = _arduino(mocker)
    keyboard.keyDown('left')
    keyboard.keyUp('left')
    assert send.call_args_list == [
        mocker.call('keyDown,216'), mocker.call('keyUp,216'),
    ]


def test_press_normalizes_key_list(mocker):
    send = _arduino(mocker)
    keyboard.press(['left', 'right'])
    assert send.call_args_list == [
        mocker.call('press,216'), mocker.call('press,215'),
    ]


def test_write_uses_hex_safe_arduino_command(mocker):
    send = _arduino(mocker)
    keyboard.write('a,b')
    send.assert_called_once_with('writeHex,612c62')


def test_arduino_failure_has_no_software_fallback(mocker):
    mocker.patch.object(keyboard, '_focusTibia')
    mocker.patch.object(
        keyboard, 'sendCommandArduino',
        side_effect=ArduinoUnavailableError('missing'),
    )
    with pytest.raises(ArduinoUnavailableError):
        keyboard.press('left')
