use herolib_mos::cloud_hypervisor::snapshot::{SnapshotInfo, SnapshotManager};
use tempfile::TempDir;
use std::path::PathBuf;

#[tokio::test]
async fn test_snapshot_manager_integration() {
    let temp_dir = TempDir::new().unwrap();
    let manager = SnapshotManager::new(temp_dir.path()).unwrap();
    
    let result = manager.create_snapshot("vm1", "snap1", "file:///tmp/snap1.snap");
    assert!(result.is_ok());
}

#[tokio::test]
async fn test_snapshot_lifecycle() {
    let temp_dir = TempDir::new().unwrap();
    let manager = SnapshotManager::new(temp_dir.path()).unwrap();
    
    manager.create_snapshot("vm1", "snap1", "file:///tmp/snap1.snap").unwrap();
    
    let snapshots = manager.list_snapshots("vm1").unwrap();
    assert_eq!(snapshots.len(), 1);
    
    manager.delete_snapshot("vm1", "snap1").unwrap();
    
    let snapshots = manager.list_snapshots("vm1").unwrap();
    assert_eq!(snapshots.len(), 0);
}

#[tokio::test]
async fn test_multiple_snapshots_per_vm() {
    let temp_dir = TempDir::new().unwrap();
    let manager = SnapshotManager::new(temp_dir.path()).unwrap();
    
    for i in 0..5 {
        let name = format!("snap{}", i);
        manager.create_snapshot("vm1", &name, &format!("file:///tmp/{}.snap", name)).unwrap();
    }
    
    let snapshots = manager.list_snapshots("vm1").unwrap();
    assert_eq!(snapshots.len(), 5);
}

#[tokio::test]
async fn test_snapshot_isolation() {
    let temp_dir = TempDir::new().unwrap();
    let manager = SnapshotManager::new(temp_dir.path()).unwrap();
    
    manager.create_snapshot("vm1", "snap1", "file:///tmp/snap1.snap").unwrap();
    manager.create_snapshot("vm2", "snap1", "file:///tmp/snap2.snap").unwrap();
    
    let vm1_snapshots = manager.list_snapshots("vm1").unwrap();
    let vm2_snapshots = manager.list_snapshots("vm2").unwrap();
    
    assert_eq!(vm1_snapshots.len(), 1);
    assert_eq!(vm2_snapshots.len(), 1);
    assert_eq!(vm1_snapshots[0].vm_id, "vm1");
    assert_eq!(vm2_snapshots[0].vm_id, "vm2");
}

#[test]
fn test_snapshot_info_structure() {
    let info = SnapshotInfo {
        vm_id: "vm1".to_string(),
        name: "snap1".to_string(),
        path: PathBuf::from("/tmp/snap1.snap"),
        timestamp: 1234567890,
        size: 1024 * 1024,
    };
    
    assert_eq!(info.vm_id, "vm1");
    assert_eq!(info.name, "snap1");
    assert_eq!(info.timestamp, 1234567890);
    assert_eq!(info.size, 1024 * 1024);
}

#[tokio::test]
async fn test_snapshot_ordering() {
    let temp_dir = TempDir::new().unwrap();
    let manager = SnapshotManager::new(temp_dir.path()).unwrap();
    
    manager.create_snapshot("vm1", "snap1", "file:///tmp/snap1.snap").unwrap();
    std::thread::sleep(std::time::Duration::from_millis(10));
    manager.create_snapshot("vm1", "snap2", "file:///tmp/snap2.snap").unwrap();
    std::thread::sleep(std::time::Duration::from_millis(10));
    manager.create_snapshot("vm1", "snap3", "file:///tmp/snap3.snap").unwrap();
    
    let snapshots = manager.list_snapshots("vm1").unwrap();
    assert_eq!(snapshots.len(), 3);
    
    assert!(snapshots[0].timestamp >= snapshots[1].timestamp);
    assert!(snapshots[1].timestamp >= snapshots[2].timestamp);
}

#[tokio::test]
async fn test_get_snapshot_path() {
    let temp_dir = TempDir::new().unwrap();
    let manager = SnapshotManager::new(temp_dir.path()).unwrap();
    
    let path = manager.get_snapshot_path("vm1", "snap1");
    assert!(path.to_string_lossy().contains("vm1"));
    assert!(path.to_string_lossy().contains("snap1.snap"));
}

#[tokio::test]
async fn test_restore_after_create() {
    let temp_dir = TempDir::new().unwrap();
    let manager = SnapshotManager::new(temp_dir.path()).unwrap();
    
    manager.create_snapshot("vm1", "snap1", "file:///tmp/snap1.snap").unwrap();
    
    let vm_dir = temp_dir.path().join("vm1");
    let snapshot_path = vm_dir.join("snap1.snap");
    std::fs::write(&snapshot_path, b"snapshot data").unwrap();
    
    let restored_path = manager.restore_snapshot("vm1", "snap1").unwrap();
    assert_eq!(restored_path, snapshot_path);
}

#[tokio::test]
async fn test_concurrent_snapshot_operations() {
    let temp_dir = TempDir::new().unwrap();
    let manager = SnapshotManager::new(temp_dir.path()).unwrap();
    
    manager.create_snapshot("vm1", "snap1", "file:///tmp/snap1.snap").unwrap();
    manager.create_snapshot("vm2", "snap1", "file:///tmp/snap2.snap").unwrap();
    
    let vm1_list = manager.list_snapshots("vm1").unwrap();
    let vm2_list = manager.list_snapshots("vm2").unwrap();
    
    assert_eq!(vm1_list.len(), 1);
    assert_eq!(vm2_list.len(), 1);
}
