use super::service::Status;
use crate::error::{Error, Result};
use blueprint_core::info;
use blueprint_remote_providers::deployment::manager_integration::RemoteDeploymentConfig;
use blueprint_remote_providers::deployment::tracker::DeploymentStatus;
use blueprint_remote_providers::deployment::tracker::DeploymentTracker;
use std::sync::Arc;
use tokio::sync::RwLock;
pub struct RemoteServiceInstance {
config: RemoteDeploymentConfig,
tracker: Arc<DeploymentTracker>,
status: Arc<RwLock<Status>>,
}
impl RemoteServiceInstance {
pub fn new(config: RemoteDeploymentConfig, tracker: Arc<DeploymentTracker>) -> Self {
Self {
config,
tracker,
status: Arc::new(RwLock::new(Status::NotStarted)),
}
}
pub async fn start(&mut self) -> Result<()> {
let provider = self
.config
.provider
.as_ref()
.map(|p| format!("{:?}", p))
.unwrap_or_else(|| "unknown".to_string());
info!(
"Starting remote service on {} (instance: {})",
provider, self.config.instance_id
);
*self.status.write().await = Status::Pending;
match self
.tracker
.get_deployment_status(&self.config.instance_id)
.await
{
Some(DeploymentStatus::Active) => {
*self.status.write().await = Status::Running;
Ok(())
}
Some(DeploymentStatus::Terminating) => {
*self.status.write().await = Status::Pending;
Err(Error::Other(
"Remote deployment is terminating and cannot be started".into(),
))
}
Some(DeploymentStatus::Terminated) => {
*self.status.write().await = Status::Finished;
Err(Error::Other(
"Remote deployment is already terminated".into(),
))
}
Some(DeploymentStatus::Failed) => {
*self.status.write().await = Status::Error;
Err(Error::Other("Remote deployment failed".into()))
}
Some(DeploymentStatus::Unknown) => {
*self.status.write().await = Status::Unknown;
Err(Error::Other("Remote deployment status unknown".into()))
}
None => {
*self.status.write().await = Status::Error;
Err(Error::Other("Remote deployment not found".into()))
}
}
}
pub async fn status(&self) -> Result<Status> {
Ok(*self.status.read().await)
}
pub async fn shutdown(&mut self) -> Result<()> {
let provider = self
.config
.provider
.as_ref()
.map(|p| format!("{:?}", p))
.unwrap_or_else(|| "unknown".to_string());
info!(
"Shutting down remote service on {} (instance: {})",
provider, self.config.instance_id
);
self.tracker
.handle_termination(&self.config.instance_id)
.await?;
*self.status.write().await = Status::Finished;
Ok(())
}
pub async fn logs(&self, _lines: usize) -> Result<Vec<String>> {
let provider = self
.config
.provider
.as_ref()
.map(|p| format!("{:?}", p))
.unwrap_or_else(|| "unknown".to_string());
Ok(vec![format!(
"[Remote logs from {} instance {} - not yet implemented]",
provider, self.config.instance_id
)])
}
}