//! Example: Transparent Process Isolation API
//!
//! This demonstrates the modern API where ALL C code
//! runs in isolated processes - nothing in the parent process.

use espresso_logic::Anonymous;
use espresso_logic::{Cover, CoverType, Cube, CubeType, Minimizable};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("=== Transparent Process Isolation API ===\n");

    println!("✓ No global state in parent process");
    println!("✓ All C code runs in isolated workers");
    println!("✓ Thread-safe by default\n");

    // Create a cover for 2 inputs, 1 output - NO C code executed!
    println!("1. Creating Cover (no C code yet)");
    let mut cover = Cover::<Anonymous, Anonymous>::anonymous(CoverType::F);
    println!("   ✓ Cover created (pure Rust data structure)\n");

    // Add cubes (XOR function)
    println!("2. Adding cubes to cover");
    cover.push(Cube::anonymous(
        &[Some(false), Some(true)],
        &[true],
        CubeType::F,
    )); // 01 -> 1
    cover.push(Cube::anonymous(
        &[Some(true), Some(false)],
        &[true],
        CubeType::F,
    )); // 10 -> 1
    println!("   ✓ Cubes added (pure Rust, no C code)\n");

    // Minimize - THIS is when the worker process runs
    println!("3. Minimizing (spawns worker process)");
    println!("   - Worker forks");
    println!("   - Worker initializes C cube structure");
    println!("   - Worker builds Cover from cube data");
    println!("   - Worker runs minimization");
    println!("   - Worker returns result via shared memory");
    println!("   - Worker terminates");

    cover = cover.minimize()?;
    println!("   ✓ Success! Result has {} cubes\n", cover.num_cubes());

    println!("=== Key Benefits ===");
    println!("• Parent process never touches C code");
    println!("• No global state in parent");
    println!("• Thread-safe without any synchronization");
    println!("• Simple, clean API with const generics\n");

    println!("✓ Complete process isolation achieved!");
    Ok(())
}
