//! Full Vision smoke — exercises every request type the crate exposes.
//!
//! Generates a test QR via Core Image at `/tmp/car-qr.png` (or runs
//! against an existing image at the same path), then validates:
//!
//!   - is_available() returns true on macOS
//!   - faces::detect on an image with no faces (empty result, no error)
//!   - barcodes::detect on a QR code (decodes the URL)
//!   - classify::classify ranks the QR as something image-classifier-y
//!   - ocr::recognize on the QR (no text, empty result)
//!
//! Run from the repo root (after generating /tmp/car-qr.png separately,
//! or rely on the swift one-liner the README documents):
//!     cd car-rs && cargo run --release -p car-vision --example vision_full_smoke

#[cfg(target_os = "macos")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
    use car_vision::{barcodes, classify, faces, is_available, ocr};

    println!("=== car-vision full smoke ===\n");

    let path = "/tmp/car-qr.png";
    if !std::path::Path::new(path).exists() {
        eprintln!(
            "missing test image {path}\n\
             Generate with:\n\n  \
             cat > /tmp/gen-qr.swift <<'EOF'\n  \
             import Foundation; import CoreImage; import AppKit\n  \
             let s = \"https://github.com/Parslee-ai/car\"\n  \
             let f = CIFilter(name: \"CIQRCodeGenerator\")!\n  \
             f.setValue(s.data(using: .utf8)!, forKey: \"inputMessage\")\n  \
             let r = NSBitmapImageRep(ciImage: f.outputImage!.transformed(by: .init(scaleX: 8, y: 8)))\n  \
             try r.representation(using: .png, properties: [:])!.write(to: URL(fileURLWithPath: \"/tmp/car-qr.png\"))\n  \
             EOF\n  \
             swift /tmp/gen-qr.swift",
        );
        std::process::exit(1);
    }

    println!("0. is_available() = {}", is_available());
    println!();

    println!("1. faces::detect (QR image, no faces expected)");
    let started = std::time::Instant::now();
    let face_results = faces::detect(path)?;
    println!(
        "   {} face(s) in {} ms",
        face_results.len(),
        started.elapsed().as_millis()
    );
    println!();

    println!("2. barcodes::detect (should decode the QR)");
    let started = std::time::Instant::now();
    let codes = barcodes::detect(path)?;
    println!(
        "   {} code(s) in {} ms:",
        codes.len(),
        started.elapsed().as_millis()
    );
    for c in &codes {
        println!(
            "     - [{}] {:?} confidence={:.3} bbox=({:.2},{:.2},{:.2},{:.2})",
            c.symbology, c.payload, c.confidence, c.x, c.y, c.w, c.h
        );
    }
    if codes.is_empty() {
        return Err("expected at least one barcode in /tmp/car-qr.png".into());
    }
    println!();

    println!("3. classify::classify (top 5)");
    let started = std::time::Instant::now();
    let cats = classify::classify(path, 5)?;
    println!(
        "   top {} in {} ms:",
        cats.len(),
        started.elapsed().as_millis()
    );
    for c in &cats {
        println!("     - {:<32}  {:.4}", c.identifier, c.confidence);
    }
    println!();

    println!("4. ocr::recognize (QR has no text)");
    let started = std::time::Instant::now();
    let text = ocr::recognize(std::path::Path::new(path), &Default::default())?;
    println!(
        "   {} observation(s) in {} ms",
        text.len(),
        started.elapsed().as_millis()
    );

    println!("\nAll Vision paths green.");
    Ok(())
}

#[cfg(not(target_os = "macos"))]
fn main() {
    eprintln!("car-vision wraps Apple Vision — macOS only.");
    std::process::exit(2);
}
