//! Audio format parsing — XMA and XWB handling.
//!
//! Xbox 360 games use **XMA** (Xbox Media Audio) as their primary audio codec.
//! XMA is a proprietary Microsoft codec derived from WMA Pro.
//!
//! ## The Challenge
//! XMA decoding requires Microsoft's proprietary XMA decoder, which is only
//! available in the Windows DirectX runtime. There are two approaches:
//!
//! ### Option A: Convert on extraction (recommended for Milestone 1)
//! Use `xma2encode.exe` (from Xbox 360 SDK) or `ffmpeg` (has partial XMA support)
//! to pre-convert all audio to OGG/WAV during the extraction step.
//!
//! ```bash
//! # Convert a single XMA file to WAV using ffmpeg
//! ffmpeg -i audio.xma output.wav
//!
//! # Or use VGMStream's test.exe for more accurate XMA decoding
//! ```
//!
//! ### Option B: XMA2 software decoder
//! The `xma2dec` project provides an open-source XMA2 decoder.
//! GitHub: https://github.com/koolkdev/xmalib (research-quality)
//!
//! ### XWB Wave Bank format
//! Xbox 360 games typically bundle audio into XWB (Xbox Wave Bank) files.
//! These are containers that hold multiple XMA streams.
//! Reference: https://github.com/microsoft/DirectXTK/tree/main/Audio

use thiserror::Error;

#[derive(Debug, Error)]
pub enum AudioError {
    #[error("Unknown audio format magic: {0:?}")]
    UnknownMagic([u8; 4]),
    #[error("XMA decoding requires pre-conversion. See audio.rs for instructions.")]
    XmaNotSupported,
    #[error("Parse error: {0}")]
    Parse(String),
}

/// An audio clip decoded to raw PCM, ready for Bevy's audio system.
#[derive(Debug, Clone)]
pub struct GameAudio {
    /// Raw PCM samples (interleaved for stereo: L R L R ...)
    pub samples: Vec<f32>,
    pub channels: u16,
    pub sample_rate: u32,
}

impl GameAudio {
    /// Parse audio from raw bytes.
    ///
    /// Currently only WAV/PCM is supported. For XMA files, pre-convert using:
    /// `ffmpeg -i file.xma file.wav`
    pub fn from_bytes(bytes: &[u8]) -> Result<Self, AudioError> {
        // Check for WAV magic
        if bytes.len() >= 4 && &bytes[..4] == b"RIFF" {
            return Self::from_wav(bytes);
        }

        // XMA magic bytes
        if bytes.len() >= 4 && (
            &bytes[..4] == b"XWB\0" || // Wave bank
            &bytes[..4] == b"XMA2"     // Raw XMA2
        ) {
            return Err(AudioError::XmaNotSupported);
        }

        Err(AudioError::UnknownMagic(
            bytes[..4.min(bytes.len())].try_into().unwrap_or([0u8; 4])
        ))
    }

    fn from_wav(bytes: &[u8]) -> Result<Self, AudioError> {
        // Minimal WAV parser for PCM files
        // A proper implementation should use the `hound` crate:
        // https://crates.io/crates/hound
        //
        // TODO: Add `hound = "3"` to Cargo.toml and implement properly
        Err(AudioError::Parse(
            "WAV parsing TODO: add `hound` crate and implement".to_string()
        ))
    }
}
