use std::sync::Arc;
use dirs::data_local_dir;
use oparl_service_facade::OParlServiceHandle;
use oparl_types::DateTime;
use pib_oparl_service::PibOParlService;
use pib_service_api_types::config::oidc::OidcConfig;
use pib_service_db_migration::Migrator;
use pib_service_inventory::InventoryProvider;
use pib_service_inventory_db::DatabaseInventoryProvider;
use sea_orm::Database;
use sea_orm_migration::MigratorTrait as _;
use tokio::{select, sync::RwLock};
mod settings;
use crate::settings::{ApiOidcSettings, ApiSettings, Settings};
const PROGRAM_NAME: &str = env!("CARGO_PKG_NAME");
#[tokio::main]
async fn main() -> anyhow::Result<()> {
env_logger::init();
let settings = Settings::load()?;
let data_dir = data_local_dir().unwrap().join("pib-service");
std::fs::create_dir_all(&data_dir)?;
let db_path = data_dir.join("inventory.sqlite?mode=rwc");
let db_url = format!("sqlite:{}", db_path.to_str().unwrap());
let db = Database::connect(db_url).await?;
Migrator::up(&db, None).await.unwrap();
let name = Some(PROGRAM_NAME.into());
let vendor = Some("https://codeberg.org/pib".parse()?);
let product = Some("https://codeberg.org/pib/pib-service".parse()?);
let now = DateTime::now();
let created = now.clone();
let modified = now.clone();
let pib_about = Some(
"An experimental OParl service developed by the \"Politik im Blick\" developers".into(),
);
let database_inventory_provider: Arc<dyn InventoryProvider> = Arc::new(
DatabaseInventoryProvider::new(db, name, vendor, product, created, modified, pib_about),
);
let service = OParlServiceHandle::new(Arc::new(RwLock::new(PibOParlService::new(
settings.oparl.base_url,
database_inventory_provider.clone(),
))));
let service_future = oparl_web_service_axum::run(service, settings.http.bind.as_slice());
if let Some(ApiSettings { oidc, http }) = settings.api.as_ref() {
let ApiOidcSettings {
issuer,
client_id,
client_secret,
} = oidc.clone();
let oidc = OidcConfig {
issuer,
client_id,
client_secret,
};
let service_api_future =
pib_service_api::run(database_inventory_provider, http.bind.as_slice(), oidc);
select! {
result = service_future => result?,
result = service_api_future => result?
}
} else {
service_future.await?;
}
Ok(())
}