"""
Integration tests for the audio parser.

All tests are skipped unless whisperx is installed AND a real audio fixture
is present at tests/golden/fixtures/interview.wav.

To run:
    pip install 'extractor[audio]'
    # place a short (< 30s) WAV at tests/golden/fixtures/interview.wav
    pytest tests/integration/test_audio.py -v
"""

from __future__ import annotations

from pathlib import Path

import pytest

# Skip the entire module if whisperx is not installed
whisperx = pytest.importorskip("whisperx", reason="whisperx not installed — skip audio tests")

FIXTURE_DIR = Path(__file__).parent.parent / "golden" / "fixtures"
AUDIO_FIXTURE = FIXTURE_DIR / "interview.wav"

pytestmark = pytest.mark.skipif(
    not AUDIO_FIXTURE.exists(),
    reason=f"Audio fixture not found at {AUDIO_FIXTURE}",
)


def test_audio_parser_imports():
    """AudioParser can be imported and instantiated."""
    from extractor.parsers.audio import AudioParser

    parser = AudioParser()
    assert ("audio/mpeg", None) in parser.handles
    assert ("audio/wav", None) in parser.handles
    assert ("audio/mp4", None) in parser.handles


def test_audio_produces_transcript_segments():
    """Audio fixture produces at least one transcript_segment element."""
    from extractor.pipeline import run

    elements = list(run(AUDIO_FIXTURE, mode="elements"))
    types = [e.element_type for e in elements]

    assert "text:transcript_segment" in types, f"Got types: {types}"

    # Every segment must have transcript_data
    for el in elements:
        if el.element_type == "text:transcript_segment":
            assert el.transcript_data is not None
            assert isinstance(el.transcript_data.start_time_s, float)
            assert isinstance(el.transcript_data.end_time_s, float)
            assert el.transcript_data.end_time_s >= el.transcript_data.start_time_s
            assert el.text.strip(), "Segment text must not be empty"


def test_audio_document_title_element():
    """Pipeline emits a meta:document_title from the filename."""
    from extractor.pipeline import run

    elements = list(run(AUDIO_FIXTURE, mode="elements"))
    titles = [e for e in elements if e.element_type == "meta:document_title"]
    assert titles, "Expected at least one meta:document_title element"
    assert AUDIO_FIXTURE.stem in titles[0].text


def test_audio_chunk_mode():
    """Audio in chunk mode produces valid ChunkRecords."""
    from extractor.pipeline import run
    from extractor.schema import ChunkRecord

    chunks = list(run(AUDIO_FIXTURE, mode="chunks"))
    assert chunks, "No chunks produced"

    for chunk in chunks:
        assert isinstance(chunk, ChunkRecord)
        assert chunk.source_filename == AUDIO_FIXTURE.name
        assert chunk.text.strip()


def test_audio_no_diarization_without_token(monkeypatch):
    """Without HF_TOKEN, diarization is skipped but transcription still works."""
    monkeypatch.delenv("HF_TOKEN", raising=False)
    from extractor.pipeline import run

    elements = list(run(AUDIO_FIXTURE, mode="elements"))
    segments = [e for e in elements if e.element_type == "text:transcript_segment"]
    assert segments, "Expected transcript segments even without diarization"

    # All speakers should be None when diarization is skipped
    for seg in segments:
        assert seg.transcript_data is not None
        # Speaker may be None (no diarization) or a string (if HF_TOKEN was set)
        assert seg.transcript_data.speaker is None or isinstance(seg.transcript_data.speaker, str)


def test_audio_word_timestamps_present():
    """Word-level timestamps are present when alignment succeeds."""
    from extractor.pipeline import run

    elements = list(run(AUDIO_FIXTURE, mode="elements"))
    segments = [e for e in elements if e.element_type == "text:transcript_segment"]
    assert segments

    # At least some segments should have word timestamps after alignment
    has_words = any(seg.transcript_data and seg.transcript_data.word_timestamps for seg in segments)
    assert has_words, "Expected word-level timestamps from whisperx alignment"


def test_unsupported_audio_mime_falls_through():
    """A .tex file is not routed to AudioParser."""
    import tempfile
    from pathlib import Path as P

    from extractor.classifier import classify
    from extractor.quarantine import run as quarantine

    with tempfile.TemporaryDirectory() as d:
        p = P(d) / "test.tex"
        p.write_text(r"\documentclass{article}\begin{document}Hello\end{document}")
        mime = quarantine(p)
        key = classify(p, mime)
        assert key[0] != "audio/mpeg"
