"""Tests for runtime/speech/stt.py.

Offline tests use FakeSTT only. The live model test is skipped unless
MENTORCORE_TEST_STT=1 is set (it requires model download).
"""

from __future__ import annotations

import os
import wave
from pathlib import Path

import pytest

FIXTURE_WAV = Path(__file__).parent.parent / "fixtures" / "audio" / "fixture.wav"


# ── FakeSTT unit tests ────────────────────────────────────────────────────────


def test_fake_stt_returns_fixed_response():
    from runtime.speech.stt import FakeSTT

    stt = FakeSTT("virtue is the highest good")
    result = stt.transcribe(b"\x00" * 100)
    assert result == "virtue is the highest good"


def test_fake_stt_default_response():
    from runtime.speech.stt import FakeSTT

    stt = FakeSTT()
    assert len(stt.transcribe(b"\x00" * 100)) > 0


def test_stt_provider_protocol():
    """FakeSTT satisfies the STTProvider Protocol."""
    from runtime.speech.stt import FakeSTT, STTProvider

    stt = FakeSTT()
    assert isinstance(stt, STTProvider)


# ── Fixture WAV integrity ─────────────────────────────────────────────────────


def test_fixture_wav_is_valid():
    """The fixture WAV can be opened and has at least 1s of audio at 16kHz."""
    assert FIXTURE_WAV.exists(), f"Missing fixture: {FIXTURE_WAV}"
    with wave.open(str(FIXTURE_WAV), "rb") as wf:
        assert wf.getnchannels() == 1
        assert wf.getsampwidth() == 2
        rate = wf.getframerate()
        frames = wf.getnframes()
    duration = frames / rate
    assert duration >= 0.5, f"Fixture too short: {duration:.2f}s"


# ── Live model test (skipped unless opted in) ─────────────────────────────────


@pytest.mark.skipif(
    os.environ.get("MENTORCORE_TEST_STT") != "1",
    reason="Set MENTORCORE_TEST_STT=1 to run live STT (downloads model)",
)
def test_transcribe_wav_file_live():
    """Real model: fixture WAV transcribed without crashing. WER not asserted (tone input)."""
    from runtime.speech.stt import transcribe_wav_file

    result = transcribe_wav_file(str(FIXTURE_WAV))
    # A sine-wave tone may produce empty or noise; just verify no exception
    assert isinstance(result, str)
