use lobe_core::engine::capture::CaptureSessionExport;
use lobe_core::error::{Result, TloxError};
use serde::Deserialize;
use crate::config;
#[derive(Debug, Deserialize)]
pub struct UploadResponse {
#[allow(dead_code)]
pub session_id: String,
#[allow(dead_code)]
pub project_id: String,
#[allow(dead_code)]
pub project_name: String,
pub event_count: usize,
}
pub async fn upload_session(session: &CaptureSessionExport) -> Result<UploadResponse> {
let config = config::load()?;
let token = config.auth.token.ok_or_else(|| {
TloxError::Auth(
"not logged in — run `lobe login` first to authorize this machine".to_string(),
)
})?;
let url = format!("{}/upload-session", config.urls.api);
let client = reqwest::Client::new();
let response = client
.post(&url)
.header("Authorization", format!("Bearer {token}"))
.json(session)
.send()
.await
.map_err(|e| TloxError::Network(format!("upload failed to reach cloud: {e}")))?;
let status = response.status();
if status == reqwest::StatusCode::UNAUTHORIZED {
return Err(TloxError::Auth(
"token was rejected — run `lobe login` to mint a fresh one".to_string(),
));
}
if !status.is_success() {
let body = response.text().await.unwrap_or_default();
return Err(TloxError::Network(format!(
"upload rejected ({status}): {body}"
)));
}
let payload: UploadResponse = response
.json()
.await
.map_err(|e| TloxError::Network(format!("could not parse upload response: {e}")))?;
Ok(payload)
}
#[allow(dead_code)]
pub fn session_url(response: &UploadResponse) -> String {
let config = config::load().unwrap_or_default();
format!(
"{}/projects/{}/sessions/{}",
config.urls.web, response.project_id, response.session_id
)
}