"""
This module test some of the behavior of action manager.
"""

from unittest.mock import Mock

import pytest

from finn.utils.action_manager import ActionManager


@pytest.fixture
def action_manager():
    """
    Unlike normal napari we use a different instance we have complete control
    over and can throw away this makes it easier.
    """
    return ActionManager()


def test_unbind_non_existing_action(action_manager):
    """
    We test that unbinding an non existing action is ok, this can happen due to
    keybindings in settings while some plugins are deactivated or upgraded.

    We emit a warning but should not fail.
    """
    with pytest.warns(UserWarning):
        assert action_manager.unbind_shortcut("napari:foo_bar") is None


def test_bind_multiple_action(action_manager):
    """
    Test we can have multiple bindings per action
    """

    action_manager.register_action(
        "napari:test_action_2", lambda: None, "this is a test action", None
    )

    action_manager.bind_shortcut("napari:test_action_2", "X")
    action_manager.bind_shortcut("napari:test_action_2", "Y")
    assert action_manager._shortcuts["napari:test_action_2"] == ["X", "Y"]


def test_bind_unbind_existing_action(action_manager):
    action_manager.register_action(
        "napari:test_action_1", lambda: None, "this is a test action", None
    )

    assert action_manager.bind_shortcut("napari:test_action_1", "X") is None
    assert action_manager.unbind_shortcut("napari:test_action_1") == ["X"]
    assert action_manager._shortcuts["napari:test_action_1"] == []


def test_bind_key_generator(action_manager):
    def _sample_generator():
        yield "X"

    action_manager.register_action(
        "napari:test_action_1",
        _sample_generator,
        "this is a test action",
        None,
    )

    with pytest.raises(ValueError, match="generator functions"):
        action_manager.bind_button("napari:test_action_1", Mock())
