use std::path::PathBuf;
use std::sync::Arc;
use crate::daemon::DaemonReloader;
use crate::policy::PolicyStore;
fn activate_stored_credential_providers(config: &mut bitrouter_sdk::config::Config) {
if let Ok(store) = bitrouter_providers::oauth::credential_store::CredentialStore::default_path()
{
bitrouter_providers::activate_stored_credential_providers(config, &store);
}
}
pub enum ReloadSource {
File(PathBuf),
Default,
}
pub struct AppReloader {
policy_store: Arc<PolicyStore>,
routing_table: Arc<bitrouter_sdk::config::ConfigRoutingTable>,
source: ReloadSource,
}
impl AppReloader {
pub fn new(
policy_store: Arc<PolicyStore>,
routing_table: Arc<bitrouter_sdk::config::ConfigRoutingTable>,
source: ReloadSource,
) -> Self {
Self {
policy_store,
routing_table,
source,
}
}
}
#[async_trait::async_trait]
impl DaemonReloader for AppReloader {
async fn reload(&self) -> anyhow::Result<()> {
let mut errors: Vec<String> = Vec::new();
let routing_outcome = match &self.source {
ReloadSource::File(path) => match bitrouter_sdk::config::load(path).await {
Ok(mut fresh) => {
bitrouter_providers::apply_builtin_defaults(&mut fresh);
crate::claude_code::enable_if_logged_in(&mut fresh);
crate::assemble::merge_registry_into(&mut fresh).await;
activate_stored_credential_providers(&mut fresh);
self.routing_table.replace_config(fresh).await
}
Err(e) => Err(e),
},
ReloadSource::Default => {
let mut fresh = bitrouter_providers::zero_config();
crate::cloud::enable_in_zero_config(&mut fresh);
bitrouter_providers::apply_builtin_defaults(&mut fresh);
crate::claude_code::enable_if_logged_in(&mut fresh);
crate::assemble::merge_registry_into(&mut fresh).await;
activate_stored_credential_providers(&mut fresh);
self.routing_table.replace_config(fresh).await
}
};
if let Err(e) = routing_outcome {
errors.push(format!("routing table: {e}"));
}
if let Err(e) = self.policy_store.reload().await {
errors.push(format!("policy store: {e}"));
}
if errors.is_empty() {
Ok(())
} else {
Err(anyhow::anyhow!(errors.join("; ")))
}
}
}