use clap::Parser;
use etwin_auth_store::mem::MemAuthStore;
use etwin_core::auth::AuthStore;
use etwin_core::clock::{Clock, VirtualClock};
use etwin_core::core::Instant;
use etwin_core::dinoparc::{DinoparcClient, DinoparcStore};
use etwin_core::email::{EmailFormatter, Mailer};
use etwin_core::forum::ForumStore;
use etwin_core::hammerfest::{HammerfestClient, HammerfestStore};
use etwin_core::link::LinkStore;
use etwin_core::oauth::OauthProviderStore;
use etwin_core::password::PasswordService;
use etwin_core::token::TokenStore;
use etwin_core::twinoid::{TwinoidClient, TwinoidStore};
use etwin_core::types::AnyError;
use etwin_core::user::UserStore;
use etwin_core::uuid::{Uuid4Generator, UuidGenerator};
use etwin_dinoparc_client::http::{HttpDinoparcClient, HttpDinoparcClientEvent};
use etwin_dinoparc_store::mem::MemDinoparcStore;
use etwin_email_formatter::json::JsonEmailFormatter;
use etwin_forum_store::mem::MemForumStore;
use etwin_hammerfest_client::HttpHammerfestClient;
use etwin_hammerfest_store::mem::MemHammerfestStore;
use etwin_link_store::mem::MemLinkStore;
use etwin_log::{Logger, NoopLogger};
use etwin_mailer::mem::MemMailer;
use etwin_oauth_client::mem::MemRfcOauthClient;
use etwin_oauth_client::RfcOauthClient;
use etwin_oauth_provider_store::mem::MemOauthProviderStore;
use etwin_password::scrypt::ScryptPasswordService;
use etwin_rest::{DevApi, RouterApi};
use etwin_services::auth::AuthService;
use etwin_services::dinoparc::DinoparcService;
use etwin_services::forum::ForumService;
use etwin_services::hammerfest::HammerfestService;
use etwin_services::oauth::OauthService;
use etwin_services::twinoid::TwinoidService;
use etwin_services::user::UserService;
use etwin_token_store::mem::MemTokenStore;
use etwin_twinoid_client::http::HttpTwinoidClient;
use etwin_twinoid_store::mem::MemTwinoidStore;
use etwin_user_store::mem::MemUserStore;
use std::sync::Arc;
#[derive(Debug, Parser)]
pub struct Args {}
fn create_api() -> RouterApi {
let dev = DevApi::new();
let clock = Arc::new(VirtualClock::new(Instant::ymd_hms(2020, 1, 1, 0, 0, 0)));
let logger: Arc<dyn for<'r> Logger<HttpDinoparcClientEvent<'r, &'r [u8]>>> = Arc::new(NoopLogger);
let hammerfest_client: Arc<dyn HammerfestClient> = Arc::new(HttpHammerfestClient::new(Arc::clone(&clock)).unwrap());
let hammerfest_store: Arc<dyn HammerfestStore> = Arc::new(MemHammerfestStore::new(Arc::clone(&clock)));
let dinoparc_client: Arc<dyn DinoparcClient> =
Arc::new(HttpDinoparcClient::new(Arc::clone(&clock), Arc::clone(&logger)).unwrap());
let dinoparc_store: Arc<dyn DinoparcStore> = Arc::new(MemDinoparcStore::new(Arc::clone(&clock)));
let forum_store: Arc<dyn ForumStore> = Arc::new(MemForumStore::new(Arc::clone(&clock), Uuid4Generator));
let link_store: Arc<dyn LinkStore> = Arc::new(MemLinkStore::new(Arc::clone(&clock)));
let user_store: Arc<dyn UserStore> = Arc::new(MemUserStore::new(Arc::clone(&clock), Uuid4Generator));
let auth_store: Arc<dyn AuthStore> = Arc::new(MemAuthStore::new(Arc::clone(&clock), Uuid4Generator));
let email_formatter: Arc<dyn EmailFormatter> = Arc::new(JsonEmailFormatter);
let mailer: Arc<dyn Mailer> = Arc::new(MemMailer::new());
let password: Arc<dyn PasswordService> = Arc::new(ScryptPasswordService::recommended_for_tests());
let oauth_provider_store: Arc<dyn OauthProviderStore> = Arc::new(MemOauthProviderStore::new(
Arc::clone(&clock),
Arc::clone(&password),
Uuid4Generator,
));
let token_store: Arc<dyn TokenStore> = Arc::new(MemTokenStore::new(Arc::clone(&clock)));
let twinoid_client: Arc<dyn TwinoidClient> = Arc::new(HttpTwinoidClient::new(Arc::clone(&clock)).unwrap());
let twinoid_oauth_client: Arc<dyn RfcOauthClient> = Arc::new(MemRfcOauthClient::new());
let twinoid_store: Arc<dyn TwinoidStore> = Arc::new(MemTwinoidStore::new(Arc::clone(&clock)));
let internal_auth_key = b"dev_secret_internal_auth".to_vec();
let auth_secret = b"dev_secret".to_vec();
let auth = Arc::new(AuthService::new(
auth_store,
Arc::clone(&clock) as Arc<dyn Clock>,
Arc::clone(&dinoparc_client),
Arc::clone(&dinoparc_store),
email_formatter,
Arc::clone(&hammerfest_client),
Arc::clone(&hammerfest_store),
Arc::clone(&link_store),
mailer,
Arc::clone(&oauth_provider_store),
Arc::clone(&password),
Arc::clone(&user_store),
Arc::clone(&twinoid_client),
Arc::clone(&twinoid_oauth_client),
Arc::clone(&twinoid_store),
Arc::new(Uuid4Generator) as Arc<dyn UuidGenerator>,
internal_auth_key,
auth_secret,
));
let dinoparc = Arc::new(DinoparcService::new(
Arc::clone(&dinoparc_client),
Arc::clone(&dinoparc_store),
Arc::clone(&link_store),
Arc::clone(&token_store),
Arc::clone(&user_store),
));
let forum = Arc::new(ForumService::new(
Arc::clone(&clock) as Arc<dyn Clock>,
Arc::clone(&forum_store),
Arc::clone(&user_store),
));
let hammerfest = Arc::new(HammerfestService::new(
Arc::clone(&hammerfest_client),
Arc::clone(&hammerfest_store),
Arc::clone(&link_store),
Arc::clone(&token_store),
Arc::clone(&user_store),
));
let oauth = Arc::new(OauthService::new(
Arc::clone(&oauth_provider_store),
Arc::clone(&user_store),
));
let twinoid = Arc::new(TwinoidService::new(
Arc::clone(&link_store),
Arc::clone(&twinoid_store),
Arc::clone(&user_store),
));
let user = Arc::new(UserService::new(
Arc::clone(&clock) as Arc<dyn Clock>,
dinoparc_client,
Arc::clone(&dinoparc_store),
Arc::clone(&hammerfest_client),
Arc::clone(&hammerfest_store),
Arc::clone(&link_store),
password,
Arc::clone(&token_store),
twinoid_client,
twinoid_store,
user_store,
));
RouterApi {
dev,
auth,
clock: Arc::clone(&clock) as Arc<dyn Clock>,
dinoparc,
forum,
hammerfest,
oauth,
twinoid,
user,
}
}
pub async fn run(_args: &Args) -> Result<(), AnyError> {
let api = create_api();
eprintln!("Started at http://localhost:3030");
axum::Server::bind(&"0.0.0.0:3030".parse().unwrap())
.serve(etwin_rest::app(api).into_make_service())
.await
.unwrap();
Ok(())
}