use tvai_sdk::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("Topaz Video AI SDK - FFmpeg Command Generation Example");
    println!("=====================================================");

    let sdk = TvaiSdk::new();

    // Example 1: Basic FFmpeg command generation
    println!("\n1. Basic FFmpeg command generation:");
    
    let upscale_template = TemplatePresets::upscale_to_4k()?;
    let basic_command = sdk.generate_ffmpeg_command(&upscale_template, "input.mp4", "output_4k.mp4")?;
    
    println!("   Template: {}", upscale_template.name);
    println!("   Command: {}", basic_command);

    // Example 2: Hardware acceleration commands
    println!("\n2. Hardware acceleration commands:");
    
    // NVIDIA GPU acceleration
    let nvidia_command = sdk.generate_ffmpeg_command_with_gpu(&upscale_template, "input.mp4", "output_nvidia.mp4", "0")?;
    println!("   NVIDIA GPU (device 0):");
    println!("   {}", nvidia_command);
    
    // Multi-GPU setup
    let multi_gpu_command = sdk.generate_ffmpeg_command_with_gpu(&upscale_template, "input.mp4", "output_multi_gpu.mp4", "0.1")?;
    println!("\n   Multi-GPU (devices 0 and 1):");
    println!("   {}", multi_gpu_command);

    // Example 3: Different codec configurations
    println!("\n3. Different codec configurations:");
    
    // H.264 with NVENC
    let h264_nvenc = sdk.generate_ffmpeg_command_with_codec(&upscale_template, "input.mp4", "output_h264_nvenc.mp4", "h264_nvenc", Some(20))?;
    println!("   H.264 NVENC (CQ 20):");
    println!("   {}", h264_nvenc);
    
    // H.265 with NVENC
    let h265_nvenc = sdk.generate_ffmpeg_command_with_codec(&upscale_template, "input.mp4", "output_h265_nvenc.mp4", "hevc_nvenc", Some(22))?;
    println!("\n   H.265 NVENC (CQ 22):");
    println!("   {}", h265_nvenc);
    
    // AMD AMF H.264
    let h264_amf = sdk.generate_ffmpeg_command_with_codec(&upscale_template, "input.mp4", "output_h264_amf.mp4", "h264_amf", Some(25))?;
    println!("\n   H.264 AMF (QP 25):");
    println!("   {}", h264_amf);
    
    // Intel QSV H.264
    let h264_qsv = sdk.generate_ffmpeg_command_with_codec(&upscale_template, "input.mp4", "output_h264_qsv.mp4", "h264_qsv", Some(23))?;
    println!("\n   H.264 QSV (Global Quality 23):");
    println!("   {}", h264_qsv);

    // Example 4: Different template types
    println!("\n4. Commands for different template types:");
    
    // Frame interpolation
    let fps_template = TemplatePresets::convert_to_60fps()?;
    let fps_command = sdk.generate_ffmpeg_command(&fps_template, "input_30fps.mp4", "output_60fps.mp4")?;
    println!("   Frame interpolation (60 FPS):");
    println!("   {}", fps_command);
    
    // Noise removal
    let denoise_template = TemplatePresets::remove_noise()?;
    let denoise_command = sdk.generate_ffmpeg_command(&denoise_template, "noisy_input.mp4", "clean_output.mp4")?;
    println!("\n   Noise removal:");
    println!("   {}", denoise_command);
    
    // Video stabilization
    let stabilize_template = TemplatePresets::stabilize_video()?;
    let stabilize_command = sdk.generate_ffmpeg_command(&stabilize_template, "shaky_input.mp4", "stable_output.mp4")?;
    println!("\n   Video stabilization:");
    println!("   {}", stabilize_command);
    
    // Slow motion
    let slowmo_template = TemplatePresets::slow_motion_4x()?;
    let slowmo_command = sdk.generate_ffmpeg_command(&slowmo_template, "normal_speed.mp4", "slow_motion.mp4")?;
    println!("\n   4x Slow motion:");
    println!("   {}", slowmo_command);

    // Example 5: Complex custom template
    println!("\n5. Complex custom template:");
    
    let complex_template = TemplateBuilder::new("Professional Enhancement")
        .description("Professional video enhancement with multiple effects")
        .enable_enhancement("prob-4")
        .enhancement_params(30, 40, 20) // denoise=30, detail=40, sharpen=20
        .enable_stabilization(75, 1) // high stabilization, full frame
        .enable_frame_interpolation("chf-3", 1.0)
        .output_settings(7, 60.0) // 4K at 60fps
        .build()?;
    
    let complex_command = sdk.generate_ffmpeg_command(&complex_template, "input_professional.mp4", "output_professional.mp4")?;
    println!("   Complex template command:");
    println!("   {}", complex_command);

    // Example 6: Batch processing commands
    println!("\n6. Batch processing commands:");
    
    let input_files = vec![
        "project/clip1.mp4".to_string(),
        "project/clip2.mp4".to_string(),
        "project/clip3.mp4".to_string(),
        "project/clip4.mp4".to_string(),
        "project/clip5.mp4".to_string(),
    ];
    
    let batch_commands = sdk.generate_batch_commands(&upscale_template, &input_files, "project/output")?;
    
    println!("   Generated {} batch commands:", batch_commands.len());
    for (i, command) in batch_commands.iter().enumerate() {
        println!("   Batch {}: {}", i + 1, command);
    }

    // Example 7: Using FFmpeg command builder for advanced scenarios
    println!("\n7. Advanced FFmpeg command builder:");
    
    // Create a custom command with multiple filters
    let advanced_command = FfmpegCommandBuilder::new("input_advanced.mp4", "output_advanced.mp4")
        .add_filter("tvai_up=model=ahq-12:scale=2:noise=0.3:details=0.2")
        .add_filter("tvai_fi=model=chr-2:fps=60")
        .add_filter("tvai_stb=model=ref-2:smoothness=8")
        .codec("hevc_nvenc")
        .quality(18)
        .hardware_accel("cuda")
        .custom_param("-preset slow")
        .custom_param("-profile:v main10")
        .build();
    
    println!("   Advanced custom command:");
    println!("   {}", advanced_command);
    
    // Create a command for HDR content
    let hdr_command = FfmpegCommandBuilder::new("input_hdr.mp4", "output_hdr.mp4")
        .add_filter("tvai_up=model=hyp-1:scale=2:sdr_ip=0.65:hdr_ip_adjust=0.3:saturate=0.8")
        .codec("hevc_nvenc")
        .quality(16)
        .custom_param("-color_primaries bt2020")
        .custom_param("-color_trc smpte2084")
        .custom_param("-colorspace bt2020nc")
        .build();
    
    println!("\n   HDR processing command:");
    println!("   {}", hdr_command);

    // Example 8: Template validation for FFmpeg
    println!("\n8. Template validation for FFmpeg generation:");
    
    let templates_to_validate = vec![
        TemplatePresets::upscale_to_4k()?,
        TemplatePresets::convert_to_60fps()?,
        TemplatePresets::remove_noise()?,
        TemplatePresets::stabilize_video()?,
        TemplatePresets::slow_motion_4x()?,
    ];
    
    for template in &templates_to_validate {
        match sdk.validate_template_for_ffmpeg(template) {
            Ok(()) => println!("   ✅ '{}' is valid for FFmpeg generation", template.name),
            Err(e) => println!("   ❌ '{}' validation failed: {}", template.name, e),
        }
    }

    // Example 9: Performance optimization suggestions
    println!("\n9. Performance optimization suggestions:");
    
    println!("   For best performance:");
    println!("   - Use GPU acceleration when available (device=0, device=0.1, etc.)");
    println!("   - Choose appropriate codec based on your hardware:");
    println!("     • NVIDIA: h264_nvenc, hevc_nvenc");
    println!("     • AMD: h264_amf, hevc_amf");
    println!("     • Intel: h264_qsv, hevc_qsv");
    println!("   - Adjust quality settings based on content:");
    println!("     • High quality: CQ/CRF 16-20");
    println!("     • Balanced: CQ/CRF 20-25");
    println!("     • Fast encoding: CQ/CRF 25-30");
    println!("   - Use multiple instances for parallel processing on high-end GPUs");
    println!("   - Consider VRAM usage with vram parameter (0.5-0.8 for shared systems)");

    println!("\n✅ FFmpeg command generation example completed successfully!");
    
    Ok(())
}
