use archetype_asset::{AssetCache, MockGpu};
use std::fs::File;
use std::io::Write;
use tempfile::Builder;

#[test]
fn test_gpu_model_loading_flow() -> anyhow::Result<()> {
    // 1. Setup
    let gpu = MockGpu::new();
    let spawner = archetype_asset::runtime::MockSpawner::new();
    let cache = AssetCache::new(gpu, spawner, 10 * 1024 * 1024);

    // 2. Create minimal valid GLB
    let dir = Builder::new().prefix("archetype_test").tempdir()?;
    let path = dir.path().join("minimal.glb");

    {
        let mut file = File::create(&path)?;

        // GLB Header
        file.write_all(b"glTF")?; // Magic
        file.write_all(&2u32.to_le_bytes())?; // Version 2

        let json_content = b"{\"asset\":{\"version\":\"2.0\"}}  "; // 28 bytes
        let bin_content = b"\0\0\0\0"; // 4 bytes dummy

        // Header (12) + Chunk0 (8+28=36) + Chunk1 (8+4=12) = 60
        let total_length = 12 + 8 + json_content.len() as u32 + 8 + bin_content.len() as u32;

        file.write_all(&total_length.to_le_bytes())?; // Total Length

        // JSON Chunk
        file.write_all(&(json_content.len() as u32).to_le_bytes())?; // Chunk Length
        file.write_all(b"JSON")?; // Chunk Type (0x4E4F534A)
        file.write_all(json_content)?; // Chunk Data

        // Binary Chunk
        file.write_all(&(bin_content.len() as u32).to_le_bytes())?; // Chunk Length
        file.write_all(b"BIN\0")?; // Chunk Type (0x004E4942)
        file.write_all(bin_content)?; // Chunk Data
    }

    // 3. Load model
    // This executes get_or_load_model -> load_model_direct (fs read + parse) -> upload_model (GPU alloc)
    let model = cache.get_or_load_model(&path)?;

    // 4. Verify
    // Minimal model has 0 meshes, but it IS a GpuModel
    assert!(model.meshes.is_empty());

    // Check cache state
    // memory_usage tracks what we "charged". estimate_model_size returns 0 for empty model.
    assert_eq!(cache.memory_usage(), 0);

    Ok(())
}
