"""
Tests unitaires pour le service ASR
"""

import asyncio
import json
import pytest
from unittest.mock import Mock, patch, AsyncMock
import tempfile
from pathlib import Path

from asr.service import ASRService
from asr.config import ASRConfig
from asr.vosk_engine import VoskEngine


class TestASRService:
    """Tests pour le service ASR principal."""

    @pytest.fixture
    def mock_mqtt_client(self):
        """Mock du client MQTT."""
        return Mock()

    @pytest.fixture
    def mock_vosk_engine(self):
        """Mock du moteur Vosk."""
        engine = Mock(spec=VoskEngine)
        engine.initialize = AsyncMock()
        engine.cleanup = AsyncMock()
        engine.reset = Mock()
        engine.process_audio = Mock()
        engine.get_final_result = Mock(return_value="bonjour skull")
        return engine

    @pytest.fixture
    def asr_service(self, mock_mqtt_client):
        """Service ASR mocké pour les tests."""
        with patch("asr.service.mqtt.Client", return_value=mock_mqtt_client):
            service = ASRService()
            return service

    def test_config_initialization(self):
        """Test l'initialisation de la configuration."""
        config = ASRConfig()
        assert config.lang == "fr"
        assert config.sample_rate == 16000
        assert config.eos_ms == 800

    def test_config_validation(self):
        """Test la validation de la configuration."""
        config = ASRConfig()
        assert config.validate() is True

        # Test configuration invalide
        config.lang = "invalid"
        assert config.validate() is False

        config.lang = "fr"
        config.eos_ms = -100
        assert config.validate() is False

    def test_vad_message_handling(self, asr_service):
        """Test le traitement des messages VAD."""
        # Test activation VAD
        payload = {"active": True}
        asr_service._handle_vad_message(payload)
        assert asr_service.vad_active is True

        # Test désactivation VAD
        payload = {"active": False}
        asr_service._handle_vad_message(payload)
        assert asr_service.vad_active is False

    def test_config_message_handling(self, asr_service):
        """Test le traitement des messages de configuration."""
        payload = {"lang": "en", "eos_ms": 1500, "vad": {"threshold": 0.7}}

        asr_service._handle_config_message(payload)

        assert asr_service.config.lang == "en"
        assert asr_service.config.eos_ms == 1500
        assert asr_service.config.vad_threshold == 0.7

    @pytest.mark.asyncio
    async def test_publish_capabilities(self, asr_service, mock_mqtt_client):
        """Test la publication des capacités."""
        asr_service.mqtt_client = mock_mqtt_client

        await asr_service._publish_capabilities()

        mock_mqtt_client.publish.assert_called_once()
        call_args = mock_mqtt_client.publish.call_args

        assert call_args[0][0] == "asr/capabilities"
        assert call_args[1]["retain"] is True

        payload = json.loads(call_args[0][1])
        assert payload["engine"] == "vosk"
        assert payload["lang"] == "fr"

    @pytest.mark.asyncio
    async def test_publish_text(self, asr_service, mock_mqtt_client):
        """Test la publication de texte transcrit."""
        asr_service.mqtt_client = mock_mqtt_client

        await asr_service._publish_text("bonjour skull")

        mock_mqtt_client.publish.assert_called_once()
        call_args = mock_mqtt_client.publish.call_args

        assert call_args[0][0] == "asr/text"

        payload = json.loads(call_args[0][1])
        assert payload["text"] == "bonjour skull"
        assert "ts_ms" in payload
