//! Scheduled batch job example.
//!
//! Demonstrates running a data sync job on a schedule. The job runs to completion,
//! then auto-restarts after a delay. Use `restart_on_success` for this pattern.

use std::{future::Future, time::Duration};

use noprocess::{Process, ProcessHandler, ProcessManager, ProcessResult, ShutdownConfig};
use tokio_util::sync::CancellationToken;

#[tokio::main]
async fn main() -> Result<(), noprocess::Error> {
    tracing_subscriber::fmt::init();

    let manager = ProcessManager::new();

    // A batch job that runs every 2 seconds
    let sync_job = Process::builder(DataSyncJob)
        .handle_id("data-sync")
        .shutdown_config(ShutdownConfig {
            graceful_timeout: Duration::from_secs(10),
            restart_on_success: true,              // Auto-restart after completion
            restart_delay: Duration::from_secs(2), // Wait 2s between runs
        })
        .on_error(|e| eprintln!("Sync job failed: {e}"))
        .build();

    let job_id = manager.add_process(sync_job).await;
    manager.start_process(&job_id).await?;

    println!("Batch job running (Ctrl+C to stop)...\n");

    // Let it run a few cycles
    tokio::time::sleep(Duration::from_secs(10)).await;

    // Graceful shutdown - will wait for current batch to finish
    println!("\n--- Requesting graceful shutdown ---");
    manager.stop_process(&job_id).await?;

    println!("Job stopped cleanly");
    Ok(())
}

struct DataSyncJob;

impl ProcessHandler for DataSyncJob {
    fn call(&self, cancel: CancellationToken) -> impl Future<Output = ProcessResult> + Send {
        async move {
            println!("[sync] Starting batch...");

            // Simulate a batch job with multiple steps
            for step in 1..=3 {
                // Check for cancellation between steps
                if cancel.is_cancelled() {
                    println!("[sync] Cancelled at step {step}, cleaning up...");
                    return Ok(());
                }

                println!("[sync] Step {step}/3: processing...");
                tokio::time::sleep(Duration::from_millis(300)).await;
            }

            println!("[sync] Batch complete!");
            Ok(()) // Will auto-restart due to restart_on_success
        }
    }
}
