use axum::Extension;
use axum::{extract::Path, response::IntoResponse, Json};
use axum_macros::debug_handler;
use solarlib::ship::{DbShip, Ship};
use tokio::process::Command;
use tracing::{error, instrument};
use solarlib::errors::Error as SolarlibError;
use solarlib::planet::Planet;
use solarlib::star::{NewPlanet, Star};
use crate::{errors::*, get_star, State};
use std::sync::Arc;
pub async fn list() -> JsonResult<Json<Vec<Planet>>> {
let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string());
let mut star = Star::new(con_url)?;
let inhabitants = star.inhabitants()?;
Ok(Json(inhabitants))
}
pub async fn get(Path(uuid): Path<String>) -> JsonResult<Json<Planet>> {
let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string());
let mut star = Star::new(con_url)?;
if let Ok(p) = star.find_planet(uuid) {
return Ok(Json(p));
} else {
return Err(ServiceError::NotFound);
}
}
pub async fn shutdown(Path(uuid): Path<String>) -> NoneResult {
let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string());
let mut star = Star::new(con_url)?;
if let Ok(p) = star.find_planet(uuid) {
p.shutdown()?;
} else {
return Err(ServiceError::NotFound);
}
Ok(())
}
pub async fn start(Path(uuid): Path<String>) -> NoneResult {
let mut s = get_star()?;
if let Ok(p) = s.find_planet(uuid) {
p.start()?;
} else {
return Err(ServiceError::NotFound);
}
Ok(())
}
pub async fn pause(Path(uuid): Path<String>) -> NoneResult {
let mut s = get_star()?;
if let Ok(p) = s.find_planet(uuid) {
p.pause()?;
} else {
return Err(ServiceError::NotFound);
}
Ok(())
}
pub async fn reboot(Path(uuid): Path<String>) -> NoneResult {
let mut s = get_star()?;
if let Ok(p) = s.find_planet(uuid) {
p.reboot()?;
} else {
return Err(ServiceError::NotFound);
}
Ok(())
}
pub async fn force_reboot(Path(uuid): Path<String>) -> NoneResult {
let mut s = get_star()?;
if let Ok(p) = s.find_planet(uuid) {
p.hard_reboot()?;
} else {
return Err(ServiceError::NotFound);
}
Ok(())
}
pub async fn force_shutdown(Path(uuid): Path<String>) -> NoneResult {
let mut s = get_star()?;
if let Ok(p) = s.find_planet(uuid) {
p.hard_shutdown()?;
} else {
return Err(ServiceError::NotFound);
}
Ok(())
}
#[debug_handler]
pub async fn new_planet(Json(new_planet): Json<NewPlanet>) -> JsonResult<Json<Planet>> {
let hw_url = std::env::var("HOMEWORLD_URL").unwrap();
let ship_shasum = new_planet.clone().ship;
let res: DbShip = reqwest::get(format!("http://{}/ships/get/{}", hw_url, ship_shasum))
.await?
.json()
.await?;
let ship: Ship = res.into();
let mut s = get_star()?;
println!("{:?}", s);
// Try to create right away, if the Ship already exists on the system, it'll go through. If
// not, we can download it by using the shasum
let r = s.planet(
new_planet.clone().name,
new_planet.max_mem,
new_planet.max_cpus,
new_planet.disk_size_mb,
ship.clone(),
Some(format!("http://{}", hw_url.clone()))
);
match r {
Err(e) => match e {
SolarlibError::MissingImage(_) => {
ship.download(&s)?;
return Ok(Json(s.planet(
new_planet.name,
new_planet.max_mem,
new_planet.max_cpus,
new_planet.disk_size_mb,
ship.clone(),
Some(format!("http://{}", hw_url.clone()))
)?));
}
_ => {
return Err(ServiceError::Solarlib(e));
}
},
Ok(r) => {
let tmp = s.inhabitants()?[0].clone();
return Ok(Json(tmp));
}
};
}
pub async fn no_planet(Path(uuid): Path<String>) -> NoneResult {
let mut s = get_star()?;
if let Ok(p) = s.find_planet(uuid) {
p.deathstar()?;
} else {
return Err(ServiceError::NotFound);
}
Ok(())
}