"""Tests for MeetingAudioReader."""

from __future__ import annotations

import json
from pathlib import Path
from uuid import uuid4

import numpy as np

from noteflow.config.constants import DEFAULT_SAMPLE_RATE
from noteflow.infrastructure.audio.reader import MeetingAudioReader
from noteflow.infrastructure.audio.writer import MeetingAudioWriter
from noteflow.infrastructure.security.crypto import AesGcmCryptoBox
from tests.conftest import approx_float

# Test constants for audio configuration
AUDIO_FRAME_SIZE_SAMPLES = 1600
"""Standard audio frame size in samples (0.1 seconds at 16kHz)."""

CUSTOM_SAMPLE_RATE_HZ = 48000
"""Custom sample rate in Hz for testing non-default sample rate handling."""

# crypto and meetings_dir fixtures are provided by tests/conftest.py


def test_audio_exists_requires_manifest(
    crypto: AesGcmCryptoBox,
    meetings_dir: Path,
) -> None:
    """audio_exists should require both audio.enc and manifest.json."""
    meeting_id = str(uuid4())
    meeting_dir = meetings_dir / meeting_id
    meeting_dir.mkdir(parents=True, exist_ok=True)

    # Only audio.enc present -> False
    (meeting_dir / "audio.enc").write_bytes(b"")
    reader = MeetingAudioReader(crypto, meetings_dir)
    assert reader.audio_exists(meeting_id) is False, "audio_exists should be False without manifest.json"

    # Add manifest.json -> True
    (meeting_dir / "manifest.json").write_text(json.dumps({"sample_rate": DEFAULT_SAMPLE_RATE}))
    assert reader.audio_exists(meeting_id) is True, "audio_exists should be True with manifest.json"


def test_reader_uses_manifest_sample_rate(
    crypto: AesGcmCryptoBox,
    meetings_dir: Path,
) -> None:
    """Reader should expose sample_rate from manifest and use it for durations."""
    meeting_id = str(uuid4())
    dek = crypto.generate_dek()
    wrapped_dek = crypto.wrap_dek(dek)

    writer = MeetingAudioWriter(crypto, meetings_dir)
    writer.open(meeting_id, dek, wrapped_dek, sample_rate=CUSTOM_SAMPLE_RATE_HZ)
    writer.write_chunk(np.zeros(AUDIO_FRAME_SIZE_SAMPLES, dtype=np.float32))  # 1600 samples @ 48kHz
    writer.close()

    reader = MeetingAudioReader(crypto, meetings_dir)
    chunks = reader.load_meeting_audio(meeting_id)

    assert reader.sample_rate == CUSTOM_SAMPLE_RATE_HZ, "reader should expose sample_rate from manifest"
    assert len(chunks) == 1, "should load exactly one chunk"
    assert chunks[0].duration == approx_float(AUDIO_FRAME_SIZE_SAMPLES / CUSTOM_SAMPLE_RATE_HZ, rel=1e-6), "chunk duration should match sample count / sample rate"
