//! Advanced usage example showing temporary file management and progress tracking

use std::path::Path;
use tvai::*;

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("Topaz Video AI Library - Advanced Usage Example");
    
    // Detect Topaz installation
    if let Some(topaz_path) = detect_topaz_installation() {
        println!("Found Topaz Video AI at: {}", topaz_path.display());
        
        // Create configuration with custom temp directory
        let config = TvaiConfig::builder()
            .topaz_path(topaz_path)
            .use_gpu(true)
            .temp_dir(std::env::temp_dir().join("tvai_advanced_example"))
            .build()?;
        
        // Create processor
        let mut processor = TvaiProcessor::new(config)?;
        println!("Processor created successfully");
        
        // Demonstrate temporary file management
        demonstrate_temp_file_management(&mut processor)?;
        
        // Demonstrate progress callback
        demonstrate_progress_callback(&processor).await?;
        
        // Demonstrate validation
        demonstrate_validation(&processor)?;
        
        // Get system information
        demonstrate_system_info(&processor).await?;
        
        println!("Advanced example completed successfully!");
    } else {
        println!("Topaz Video AI not found. Please install it first.");
    }
    
    Ok(())
}

fn demonstrate_temp_file_management(processor: &mut TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("\n=== Temporary File Management Demo ===");
    
    let operation_id = processor.generate_operation_id();
    println!("Generated operation ID: {}", operation_id);
    
    // Create some temporary files
    let temp_video = processor.create_temp_path(&operation_id, "input.mp4");
    let temp_output = processor.create_temp_path(&operation_id, "output.mp4");
    let temp_dir = processor.create_temp_dir(&operation_id)?;
    
    println!("Created temp files:");
    println!("  Video: {}", temp_video.display());
    println!("  Output: {}", temp_output.display());
    println!("  Directory: {}", temp_dir.display());
    
    // Create a unique temp file
    let unique_temp = processor.create_unique_temp_path("unique.tmp");
    println!("  Unique: {}", unique_temp.display());
    
    // Get temp manager info
    println!("Temp manager tracking {} files", processor.temp_manager().file_count());
    
    // Clean up operation files
    processor.cleanup_temp_files(&operation_id)?;
    println!("Cleaned up operation files");
    
    Ok(())
}

async fn demonstrate_progress_callback(processor: &TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("\n=== Progress Callback Demo ===");
    
    // Create a progress callback
    let progress_callback: ProgressCallback = Box::new(|progress| {
        let percentage = (progress * 100.0) as u32;
        println!("Progress: {}%", percentage);
    });
    
    // Simulate FFmpeg command execution with progress
    let args = ["-version"];
    let _output = processor.execute_ffmpeg_command(&args, false, Some(&progress_callback)).await?;
    
    println!("Command executed with progress tracking");
    
    Ok(())
}

fn demonstrate_validation(processor: &TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("\n=== Validation Demo ===");
    
    // Test input file validation (this will fail since file doesn't exist)
    let test_input = Path::new("nonexistent_input.mp4");
    match processor.validate_input_file(test_input) {
        Ok(_) => println!("Input file validation passed"),
        Err(e) => println!("Input file validation failed (expected): {}", e),
    }
    
    // Test output path validation
    let test_output = processor.temp_dir().join("test_output.mp4");
    match processor.validate_output_path(&test_output) {
        Ok(_) => println!("Output path validation passed"),
        Err(e) => println!("Output path validation failed: {}", e),
    }
    
    Ok(())
}

async fn demonstrate_system_info(processor: &TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("\n=== System Information Demo ===");
    
    // Get FFmpeg versions
    if let Ok(system_version) = processor.get_ffmpeg_version(false).await {
        println!("System FFmpeg: {}", system_version.lines().next().unwrap_or("Unknown"));
    }
    
    if let Ok(topaz_version) = processor.get_ffmpeg_version(true).await {
        println!("Topaz FFmpeg: {}", topaz_version.lines().next().unwrap_or("Unknown"));
    }
    
    // Check GPU availability
    println!("GPU enabled: {}", processor.is_gpu_enabled());
    println!("GPU available: {}", processor.is_gpu_available());
    
    // Get system detection info
    let gpu_info = detect_gpu_support();
    println!("GPU Info: CUDA={}, OpenCL={}", gpu_info.cuda_available, gpu_info.opencl_available);
    
    let ffmpeg_info = detect_ffmpeg();
    println!("FFmpeg Info: System={}, Topaz={}", ffmpeg_info.system_available, ffmpeg_info.topaz_available);
    
    // Create sample metadata
    let metadata = processor.create_metadata(
        "sample_operation".to_string(),
        Path::new("sample_input.mp4"),
        "scale=2.0,model=iris-3".to_string(),
    );
    println!("Sample metadata: operation_id={}, used_gpu={}", metadata.operation_id, metadata.used_gpu);
    
    Ok(())
}
