from __future__ import annotations

import tempfile
import unittest
import wave
from pathlib import Path
from unittest import mock

from app.livekit.runtime.initial_greeting_audio_cache import InitialGreetingAudioCache


class InitialGreetingAudioCacheTests(unittest.IsolatedAsyncioTestCase):
    def test_cache_defaults_are_enabled_and_bounded(self) -> None:
        with mock.patch.dict("os.environ", {}, clear=True):
            cache = InitialGreetingAudioCache()

        self.assertTrue(cache.enabled)
        self.assertEqual(cache._max_chars, 1_000)
        self.assertEqual(cache._ttl_s, 3_600)
        self.assertEqual(cache._max_entries, 32)
        self.assertEqual(cache._max_bytes, 16 * 1024 * 1024)
        self.assertEqual(cache._max_agent_variants, 1)
        self.assertEqual(cache._disable_ttl_s, 300)
        key = cache.key_for(
            agent="conta",
            text="Olá, como posso ajudar?",
            provider="xAI",
            voice="ara",
            language="pt-BR",
            sample_rate=24000,
        )
        self.assertIsNotNone(key)
        assert key is not None
        self.assertEqual(key.agent, "conta")

    async def test_store_writes_atomic_pcm_wav_for_matching_key(self) -> None:
        with tempfile.TemporaryDirectory() as directory:
            with mock.patch.dict(
                "os.environ",
                {
                    "INITIAL_GREETING_AUDIO_CACHE_ENABLED": "1",
                    "INITIAL_GREETING_AUDIO_CACHE_DIR": directory,
                },
                clear=True,
            ):
                cache = InitialGreetingAudioCache()
                key = cache.key_for(
                    agent="conta",
                    text="Olá, como posso ajudar?",
                    provider="xAI",
                    voice="ara",
                    language="pt-BR",
                    sample_rate=24000,
                )
                assert key is not None
                await cache.store_pcm(key, b"\x00\x00" * 240)

            path = Path(directory) / f"{key.digest}.wav"
            self.assertTrue(path.is_file())
            with wave.open(str(path), "rb") as rendered:
                self.assertEqual(rendered.getnchannels(), 1)
                self.assertEqual(rendered.getsampwidth(), 2)
                self.assertEqual(rendered.getframerate(), 24000)
                self.assertEqual(rendered.getnframes(), 240)
