/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2026 metamuffin <metamuffin.org>
*/

use crate::ContainerFormat;
use anyhow::Result;
use std::io::Read;
use winter_ebml::{Ebml, EbmlHeader, read_vint_slice};
use winter_matroska::MatroskaFile;

pub fn detect_container_format(reader: &mut dyn Read) -> Result<Option<ContainerFormat>> {
    let mut data = Vec::new();
    reader.take(128).read_to_end(&mut data)?;
    if test_flac(&data) {
        return Ok(Some(ContainerFormat::Flac));
    }
    if let Some(f) = test_matroska(&data) {
        return Ok(Some(f));
    }
    Ok(None)
}

fn test_flac(data: &[u8]) -> bool {
    data.starts_with(b"fLaC")
}

fn test_matroska(mut data: &[u8]) -> Option<ContainerFormat> {
    let tag = read_vint_slice(&mut data)?;
    if tag != MatroskaFile::TAG_EBML_HEADER {
        return None;
    };
    let size = read_vint_slice(&mut data)? as usize;
    if size > data.len() {
        return None;
    }
    let header = EbmlHeader::read(&data[..size]).ok()?;
    match header.doc_type.as_str() {
        "matroska" => Some(ContainerFormat::Matroska),
        "webm" => Some(ContainerFormat::Webm),
        _ => None,
    }
}

#[test]
fn verify_matroska() {
    // WebM
    let sample = "\
1a45dfa39f4286810142f7810142f2810442f381084282847765626d4287\
8104428581021853806701000000088a9c1a114d9b74bc4dbb8b53ab8415\
49a96653ac81a14dbb8b53ab841654ae6b53ac81d64dbb8c53ab841254c3\
6753ac8201a04dbb8e53ab841c53bb6b53ac84088a9accec010000000000\
0057000000000000";
    let sample = hex::decode(sample).unwrap();
    assert_eq!(test_matroska(&sample), Some(ContainerFormat::Webm));

    // Matroska
    let sample = "\
1a45dfa3a34286810142f7810142f2810442f381084282886d6174726f73\
6b61428781044285810218538067010000005d66b4a2114d9b74c2bf8492\
1ae3e14dbb8b53ab841549a96653ac81a14dbb8b53ab841654ae6b53ac81\
ef4dbb8c53ab841254c36753ac82019b4dbb8e53ab841c53bb6b53ac845d\
66a14aec01000000";
    let sample = hex::decode(sample).unwrap();
    assert_eq!(test_matroska(&sample), Some(ContainerFormat::Matroska));

    // GIF
    let sample = "\
47494638396100010001f71f000000002400004800006c0000900000b400\
00d80000fc00000024002424004824006c2400902400b42400d82400fc24\
000048002448004848006c4800904800b44800d84800fc4800006c00246c\
00486c006c6c00906c00b46c00d86c00fc6c000090002490004890006c90\
00909000b49000d8";
    let sample = hex::decode(sample).unwrap();
    assert_eq!(test_matroska(&sample), None)
}
