"""T-03: NotificationCommand entity tests — Resolve and Execute behaviors."""
from unittest.mock import MagicMock

from horn.notify import NotificationCommand, NotificationType, ResolveError


class TestNotificationType:
    def test_all_four_types_exist(self):
        assert NotificationType.VERIFY
        assert NotificationType.START
        assert NotificationType.DONE
        assert NotificationType.CONFIRM


class TestResolve:
    def test_no_args_resolves_to_verify(self):
        cmd = NotificationCommand.resolve(notification_type=None, message=None)
        assert cmd.notification_type == NotificationType.VERIFY

    def test_start_arg_resolves_correctly(self):
        cmd = NotificationCommand.resolve(notification_type="start", message=None)
        assert cmd.notification_type == NotificationType.START

    def test_done_arg_resolves_correctly(self):
        cmd = NotificationCommand.resolve(notification_type="done", message=None)
        assert cmd.notification_type == NotificationType.DONE

    def test_confirm_arg_resolves_correctly(self):
        cmd = NotificationCommand.resolve(notification_type="confirm", message=None)
        assert cmd.notification_type == NotificationType.CONFIRM

    def test_resolved_text_defaults_verify(self):
        cmd = NotificationCommand.resolve(notification_type=None, message=None)
        assert cmd.resolved_text == "Horn 已就绪，等待任务通知"

    def test_resolved_text_defaults_start(self):
        cmd = NotificationCommand.resolve(notification_type="start", message=None)
        assert cmd.resolved_text == "老板，我开始执行任务了"

    def test_resolved_text_defaults_done(self):
        cmd = NotificationCommand.resolve(notification_type="done", message=None)
        assert cmd.resolved_text == "老板，任务已完成"

    def test_resolved_text_defaults_confirm(self):
        cmd = NotificationCommand.resolve(notification_type="confirm", message=None)
        assert cmd.resolved_text == "老板，有事情需要你确认"

    def test_message_none_uses_default_text(self):
        cmd = NotificationCommand.resolve(notification_type="done", message=None)
        assert cmd.resolved_text == "老板，任务已完成"


class TestExecute:
    def _make_cmd(self, text="老板，任务已完成"):
        return NotificationCommand.resolve(notification_type="done", message=text if text != "老板，任务已完成" else None)

    def test_execute_success_sets_success_true(self):
        cmd = self._make_cmd()
        mock_tts = MagicMock()
        cmd.execute(mock_tts)
        assert cmd.success is True
        assert cmd.error_message == ""

    def test_execute_calls_tts_speak_with_resolved_text(self):
        cmd = self._make_cmd()
        mock_tts = MagicMock()
        cmd.execute(mock_tts)
        mock_tts.speak.assert_called_once_with(cmd.resolved_text)

    def test_execute_failure_sets_success_false(self):
        from horn.tts.base import TTSUnavailableError
        cmd = self._make_cmd()
        mock_tts = MagicMock()
        mock_tts.speak.side_effect = TTSUnavailableError("SAPI not available")
        cmd.execute(mock_tts)
        assert cmd.success is False
        assert cmd.error_message != ""

    def test_execute_timeout_sets_success_false(self):
        from horn.tts.base import TTSTimeoutError
        cmd = self._make_cmd()
        mock_tts = MagicMock()
        mock_tts.speak.side_effect = TTSTimeoutError("timed out")
        cmd.execute(mock_tts)
        assert cmd.success is False
        assert cmd.error_message != ""
