//! tidalDB + Actix-web: embedding a tidalDB instance in an Actix-web server.
//!
//! Demonstrates:
//! - Wrapping `TidalDb` in `Arc` for shared ownership
//! - Passing the instance via `web::Data<Arc<TidalDb>>`
//! - A `/health` route that calls `health_check()`
//! - Graceful shutdown via Actix's built-in signal handling
//!
//! `TidalDb` is not `Clone`, so it is wrapped in `Arc`. `web::Data` then
//! wraps the `Arc`, giving each handler a cheap clone of the pointer.
//!
//! # Running
//!
//! ```bash
//! cargo run --example actix_embedding --manifest-path tidal/Cargo.toml
//! # Then: curl http://127.0.0.1:3001/health
//! ```

use std::sync::Arc;

use actix_web::{App, HttpResponse, HttpServer, web};
use tidaldb::TidalDb;

async fn health(db: web::Data<Arc<TidalDb>>) -> HttpResponse {
    match db.health_check() {
        Ok(()) => HttpResponse::Ok().body("ok"),
        Err(_) => HttpResponse::ServiceUnavailable().body("degraded"),
    }
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    tracing_subscriber::fmt()
        .with_env_filter("tidaldb=debug")
        .init();

    // Open tidalDB; map TidalError -> io::Error so Actix's Result type aligns.
    let db = Arc::new(
        TidalDb::builder()
            .ephemeral()
            .open()
            .map_err(std::io::Error::other)?,
    );

    // Wrap in web::Data so Actix can clone it cheaply into each worker thread.
    let db_data = web::Data::new(Arc::clone(&db));

    println!("listening on http://127.0.0.1:3001");
    println!("  GET /health  -> tidalDB health check");
    println!("press Ctrl+C to stop");

    HttpServer::new(move || {
        App::new()
            .app_data(db_data.clone())
            .route("/health", web::get().to(health))
    })
    .bind("127.0.0.1:3001")?
    .run()
    .await?;

    // `db` drops here, triggering TidalDb::drop() -> shutdown_inner().
    Ok(())
}
