mod apps;
mod err;

use std::sync::Arc;

use parking_lot::Mutex;

use qsu::rt::RunCtx;

const SVCNAME: &str = "svctest";

/// Make sure that `init()`, `run()` and `shutdown()` are called for the sync
/// case.
#[test]
fn all_sync_callbacks() {
  let runctx = RunCtx::new(SVCNAME).test_mode();

  let visited = apps::Visited::default();

  assert!(!visited.init);
  assert!(!visited.run);
  assert!(!visited.shutdown);

  let visited = Arc::new(Mutex::new(visited));

  let svcevt_handler = Box::new(move |_msg| {});
  let rt_handler = Box::new(apps::MySyncService {
    visited: Arc::clone(&visited),
    ..Default::default()
  });
  let Ok(()) = runctx.run_sync(svcevt_handler, rt_handler) else {
    panic!("run_sync() unexpectedly failed");
  };

  let visited = Arc::into_inner(visited)
    .expect("Unable to into_inner Arc")
    .into_inner();
  assert!(visited.init);
  assert!(visited.run);
  assert!(visited.shutdown);
}

/// Make sure that `init()`, `run()` and `shutdown()` are called for the tokio
/// case.
#[cfg(feature = "tokio")]
#[test]
fn all_tokio_callbacks() {
  let runctx = RunCtx::new(SVCNAME).test_mode();

  let visited = apps::Visited::default();

  assert!(!visited.init);
  assert!(!visited.run);
  assert!(!visited.shutdown);

  let visited = Arc::new(Mutex::new(visited));

  let svcevt_handler = Box::new(move |_msg| {});
  let rt_handler = Box::new(apps::MyTokioService {
    visited: Arc::clone(&visited),
    ..Default::default()
  });
  let Ok(()) = runctx.run_tokio(None, svcevt_handler, rt_handler) else {
    panic!("run_sync() unexpectedly failed");
  };

  let visited = Arc::into_inner(visited)
    .expect("Unable to into_inner Arc")
    .into_inner();
  assert!(visited.init);
  assert!(visited.run);
  assert!(visited.shutdown);
}


/// Make sure that `init()`, `run()` and `shutdown()` are called for the Rocket
/// case.
#[cfg(feature = "rocket")]
#[test]
fn all_rocket_callbacks() {
  let runctx = RunCtx::new(SVCNAME).test_mode();

  let visited = apps::Visited::default();

  assert!(!visited.init);
  assert!(!visited.run);
  assert!(!visited.shutdown);

  let visited = Arc::new(Mutex::new(visited));

  let svcevt_handler = Box::new(move |_msg| {});
  let rt_handler = Box::new(apps::MyRocketService {
    visited: Arc::clone(&visited),
    ..Default::default()
  });

  let Ok(()) = runctx.run_rocket(svcevt_handler, rt_handler) else {
    panic!("run_sync() unexpectedly failed");
  };

  let visited = Arc::into_inner(visited)
    .expect("Unable to into_inner Arc")
    .into_inner();
  assert!(visited.init);
  assert!(visited.run);
  assert!(visited.shutdown);
}

// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :
