use crate::browser::cdp::{CdpClient, CdpSession};
use crate::browser::launcher::BrowserLauncher;
use crate::browser::profile::BrowserProfile;
use crate::error::{BrowsingError, Result};
use std::sync::Arc;
pub struct SessionManager {
profile: BrowserProfile,
cdp_client: Option<Arc<CdpClient>>,
cdp_url: Option<String>,
launcher: Option<BrowserLauncher>,
}
impl SessionManager {
pub fn new(profile: BrowserProfile) -> Self {
Self {
profile,
cdp_client: None,
cdp_url: None,
launcher: None,
}
}
pub fn with_cdp_url(mut self, cdp_url: String) -> Self {
self.cdp_url = Some(cdp_url);
self
}
pub async fn start(&mut self) -> Result<String> {
let cdp_url = if let Some(ref cdp_url) = self.cdp_url {
cdp_url.clone()
} else {
let mut launcher = BrowserLauncher::new(self.profile.clone());
let cdp_url = launcher.launch().await?;
self.launcher = Some(launcher);
self.cdp_url = Some(cdp_url.clone());
cdp_url
};
let mut client = CdpClient::new(cdp_url.clone());
client.start().await?;
let client_arc = Arc::new(client);
self.cdp_client = Some(Arc::clone(&client_arc));
Ok(cdp_url)
}
pub async fn stop(&mut self) -> Result<()> {
if let Some(client) = self.cdp_client.take() {
client.close().await;
drop(client);
}
tokio::task::yield_now().await;
if let Some(ref mut launcher) = self.launcher {
launcher.stop().await?;
}
self.launcher = None;
Ok(())
}
pub fn get_cdp_client(&self) -> Result<Arc<CdpClient>> {
self.cdp_client
.as_ref()
.map(Arc::clone)
.ok_or_else(|| BrowsingError::Browser("No active CDP client".to_string()))
}
pub fn is_active(&self) -> bool {
self.cdp_client.is_some()
}
pub async fn create_session(
&self,
target_id: String,
_session_id: Option<String>,
) -> Result<CdpSession> {
let client = self.get_cdp_client()?;
CdpSession::for_target(client, target_id, None).await
}
}