mod api_keys;
mod app_error;
mod app_state;
mod auth;
mod channel_selections;
mod channels;
mod csrf;
mod guards;
mod messages;
mod nav_state;
mod projects;
mod router;
mod schema;
mod sessions;
mod settings;
mod team_memberships;
mod teams;
mod users;
mod v0_router;

use tracing_subscriber::EnvFilter;

use crate::{
    app_state::{AppState, Mailer},
    router::new_router,
    sessions::PgStore,
    settings::Settings,
};

#[tokio::main]
async fn main() {
    let settings = Settings::load().unwrap();

    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .init();

    let database_url = settings.database_url.clone();
    let manager =
        deadpool_diesel::postgres::Manager::new(database_url, deadpool_diesel::Runtime::Tokio1);
    let db_pool = deadpool_diesel::postgres::Pool::builder(manager)
        .build()
        .unwrap();
    let session_store = PgStore::new(db_pool.clone());
    let mailer_creds = lettre::transport::smtp::authentication::Credentials::new(
        settings.email.smtp_username.clone(),
        settings.email.smtp_password.clone(),
    );
    let mailer = Mailer(
        lettre::SmtpTransport::starttls_relay(&settings.email.smtp_server)
            .unwrap()
            .credentials(mailer_creds)
            .build(),
    );
    let reqwest_client = reqwest::ClientBuilder::new()
        .https_only(true)
        .build()
        .unwrap();
    let oauth_client = auth::new_oauth_client(&settings).unwrap();

    let app_state = AppState {
        db_pool,
        mailer,
        oauth_client,
        reqwest_client,
        session_store,
        settings: settings.clone(),
    };

    let router = new_router(app_state);

    let listener = tokio::net::TcpListener::bind((settings.host.clone(), settings.port.clone()))
        .await
        .unwrap();
    tracing::info!(
        "App running at http://{}:{}{}",
        settings.host,
        settings.port,
        settings.base_path
    );
    axum::serve(listener, router).await.unwrap();
}
