//! Example demonstrating async I/O support in the TACO format
//!
//! This example shows how to use the AsyncWriter and AsyncReader
//! when the "async" feature is enabled.

#[cfg(feature = "async")]
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    use ndarray::Array2;
    use taco_format::{
        AsyncReader, AsyncWriter, AtomMetadata, CompressionSettings, Frame, FrameData,
        SimulationMetadata,
    };
    use tempfile::NamedTempFile;

    println!("Creating async TACO writer...");

    // Create temporary file
    let temp_file = NamedTempFile::new()?;
    let temp_path = temp_file.path().to_path_buf();

    // Set up metadata
    let simulation_metadata = SimulationMetadata::default();
    let atom_metadata = AtomMetadata::new();
    let compression_settings = CompressionSettings::default();

    // Create async writer
    let mut writer = AsyncWriter::create(
        &temp_path,
        3,     // 3 atoms
        0.001, // 1 fs time step
        simulation_metadata,
        atom_metadata,
        compression_settings,
    )
    .await?;

    println!("Writing frames async...");

    // Write some sample frames
    for i in 0..5 {
        let positions = Array2::from_shape_vec(
            (3, 3),
            vec![
                i as f32, 0.0, 0.0, // atom 1
                0.0, i as f32, 0.0, // atom 2
                0.0, 0.0, i as f32, // atom 3
            ],
        )?;

        let frame_data = FrameData::new(positions);
        let frame = Frame::new(i, i as f64 * 0.001, frame_data);

        writer.write_frame(frame).await?;
    }

    // Finish writing
    writer.finish().await?;
    println!("Finished writing {} frames", 5);

    // Now read back async
    println!("Reading back with async reader...");
    let mut reader = AsyncReader::open(&temp_path).await?;

    if let Some(header) = reader.header() {
        println!(
            "File contains {} atoms and {} frames",
            header.num_atoms,
            reader.num_frames()
        );
    }

    // Read first frame
    let frame = reader.read_frame(0).await?;
    println!("First frame time: {} ps", frame.time);
    if let Some(positions) = &frame.data.positions {
        println!("First atom position: {:?}", positions.row(0));
    }

    // Read last frame
    let frame = reader.read_frame(4).await?;
    println!("Last frame time: {} ps", frame.time);
    if let Some(positions) = &frame.data.positions {
        println!("First atom position: {:?}", positions.row(0));
    }

    println!("Async I/O example completed successfully!");

    Ok(())
}

#[cfg(not(feature = "async"))]
fn main() {
    println!("This example requires the 'async' feature to be enabled.");
    println!("Run with: cargo run --example async_example --features async");
}
