from time import time

from src.gameplay import smartSync


def _context(smart=True, verifyAt=0):
    return {
        'ng_actionBar': {'smartHotkeys': smart, 'lastVerifyAt': verifyAt},
        'ng_screenshot': [],
        'healing': {
            'potions': {
                'firstHealthPotion': {'item': 266, 'slot': 3},
                'firstManaPotion': {'item': 268, 'slot': 7},
            },
            'spells': {
                'criticalHealing': {'spell': 'exura vita', 'slot': 1},
                'lightHealing': {'spell': None, 'slot': None},
                'utura': {'spell': None, 'slot': None},
                'uturaGran': {'spell': None, 'slot': None},
            },
        },
        'ng_comboSpells': {'items': []},
    }


def test_skips_when_smart_mode_off(mocker):
    matchSpy = mocker.patch.object(smartSync, 'matchSlotImage')

    smartSync.autoSyncActionBar(_context(smart=False))

    matchSpy.assert_not_called()


def test_throttles_verification(mocker):
    matchSpy = mocker.patch.object(smartSync, 'matchSlotImage')

    smartSync.autoSyncActionBar(_context(verifyAt=time()))

    matchSpy.assert_not_called()


def test_fresh_bindings_need_no_rescan(mocker):
    mocker.patch.object(smartSync, 'getSlotImage', return_value=object())
    mocker.patch.object(smartSync, 'matchSlotImage', return_value=0)
    detectSpy = mocker.patch.object(smartSync, 'detectSlotItems')

    smartSync.autoSyncActionBar(_context())

    detectSpy.assert_not_called()


def test_stale_bindings_trigger_rescan_and_update(mocker):
    mocker.patch.object(smartSync, 'getSlotImage', return_value=object())
    mocker.patch.object(smartSync, 'matchSlotImage', return_value=None)
    mocker.patch.object(smartSync, 'detectSlotItems', return_value={266: 4})
    mocker.patch.object(
        smartSync, 'detectSlotSpells', return_value={'exura vita': 2})
    logSpy = mocker.patch.object(smartSync, 'logEvent')
    context = _context()

    smartSync.autoSyncActionBar(context)

    assert context['ng_actionBar']['slots'] == {'266': 4}
    assert context['healing']['potions']['firstHealthPotion']['slot'] == 4
    assert context['healing']['potions']['firstManaPotion']['slot'] is None
    assert context['healing']['spells']['criticalHealing']['slot'] == 2
    logSpy.assert_called_once()
