use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use ag_forge::ReviewRequestClient;
use tokio::sync::mpsc;
use crate::app::AppEvent;
use crate::app::session::Clock;
use crate::db::AppRepositories;
use crate::domain::agent::AgentKind;
use crate::domain::session::SessionId;
use crate::infra::agent::AgentUsageProbe;
use crate::infra::app_server::AppServerClient;
use crate::infra::fs::FsClient;
use crate::infra::git::GitClient;
use crate::infra::review_comment_cache::ReviewCommentCache;
pub(crate) type SessionUpdateVersionMap = Arc<Mutex<HashMap<SessionId, u64>>>;
pub(crate) struct AppServiceDeps {
pub(crate) agent_usage_probe: Arc<dyn AgentUsageProbe>,
pub(crate) app_server_client_override: Option<Arc<dyn AppServerClient>>,
pub(crate) available_agent_kinds: Vec<AgentKind>,
pub(crate) fs_client: Arc<dyn FsClient>,
pub(crate) git_client: Arc<dyn GitClient>,
pub(crate) repositories: AppRepositories,
pub(crate) review_request_client: Arc<dyn ReviewRequestClient>,
}
pub struct AppServices {
agent_usage_probe: Arc<dyn AgentUsageProbe>,
available_agent_kinds: Arc<[AgentKind]>,
app_server_client_override: Option<Arc<dyn AppServerClient>>,
base_path: PathBuf,
clock: Arc<dyn Clock>,
event_tx: mpsc::UnboundedSender<AppEvent>,
fs_client: Arc<dyn FsClient>,
git_client: Arc<dyn GitClient>,
repositories: AppRepositories,
review_comment_cache: ReviewCommentCache,
review_request_client: Arc<dyn ReviewRequestClient>,
session_update_versions: SessionUpdateVersionMap,
}
impl AppServices {
pub(crate) fn new(
base_path: PathBuf,
clock: Arc<dyn Clock>,
event_tx: mpsc::UnboundedSender<AppEvent>,
deps: AppServiceDeps,
) -> Self {
let AppServiceDeps {
agent_usage_probe,
app_server_client_override,
available_agent_kinds,
fs_client,
git_client,
repositories,
review_request_client,
} = deps;
Self {
agent_usage_probe,
available_agent_kinds: Arc::<[AgentKind]>::from(available_agent_kinds),
app_server_client_override,
base_path,
clock,
event_tx,
fs_client,
git_client,
repositories,
review_comment_cache: ReviewCommentCache::default(),
review_request_client,
session_update_versions: Arc::default(),
}
}
pub(crate) fn base_path(&self) -> &Path {
self.base_path.as_path()
}
pub(crate) fn available_agent_kinds(&self) -> Vec<AgentKind> {
self.available_agent_kinds.as_ref().to_vec()
}
pub(crate) fn agent_usage_probe(&self) -> Arc<dyn AgentUsageProbe> {
Arc::clone(&self.agent_usage_probe)
}
pub(crate) fn db(&self) -> &AppRepositories {
&self.repositories
}
pub(crate) fn clock(&self) -> Arc<dyn Clock> {
Arc::clone(&self.clock)
}
pub(crate) fn emit_app_event(&self, event: AppEvent) {
let _ = self.event_tx.send(event);
}
pub(crate) fn event_sender(&self) -> mpsc::UnboundedSender<AppEvent> {
self.event_tx.clone()
}
pub(crate) fn fs_client(&self) -> Arc<dyn FsClient> {
Arc::clone(&self.fs_client)
}
pub(crate) fn git_client(&self) -> Arc<dyn GitClient> {
Arc::clone(&self.git_client)
}
pub(crate) fn review_request_client(&self) -> Arc<dyn ReviewRequestClient> {
Arc::clone(&self.review_request_client)
}
pub(crate) fn session_update_versions(&self) -> SessionUpdateVersionMap {
Arc::clone(&self.session_update_versions)
}
pub(crate) fn review_comment_cache(&self) -> ReviewCommentCache {
self.review_comment_cache.clone()
}
pub(crate) fn app_server_client_override(&self) -> Option<Arc<dyn AppServerClient>> {
self.app_server_client_override.as_ref().map(Arc::clone)
}
}