Documentation
use crate::error::ContextWrapper;
use anyhow::Ok;
use std::time::Duration;
use tracing::info;

pub struct DbConfig<'a> {
    pub host: &'a str,
    pub port: u16,
    pub name: &'a str,
    pub user: &'a str,
    pub password: &'a str,
    pub connection_timeout_secs: u64,
}
impl<'a> DbConfig<'a> {
    pub async fn connect_db(self) -> anyhow::Result<deadpool_postgres::Pool> {
        let mut db_cfg = deadpool_postgres::Config::new();
        db_cfg.host = Some(self.host.to_owned());
        db_cfg.port = Some(self.port);
        db_cfg.dbname = Some(self.name.to_owned());
        db_cfg.user = Some(self.user.to_owned());
        db_cfg.password = Some(self.password.to_owned());
        db_cfg.connect_timeout = Some(Duration::from_secs(self.connection_timeout_secs));

        let mut builder =
            openssl::ssl::SslConnector::builder(openssl::ssl::SslMethod::tls()).anyhow()?;
        builder.set_verify(openssl::ssl::SslVerifyMode::NONE);
        let connector = postgres_openssl::MakeTlsConnector::new(builder.build());

        db_cfg
            .create_pool(Some(deadpool_postgres::Runtime::Tokio1), connector)
            .anyhow()
    }
}

pub async fn connect_database(cfg: DbConfig<'_>) -> anyhow::Result<deadpool_postgres::Pool> {
    info!("Connecting postgres db...");
    info!("Connecting postgres at {}:{}", &cfg.host, cfg.port);
    let db = cfg.connect_db().await.anyhow()?;
    let _ = db.get().await.anyhow_with("Postgres connection failed");
    info!("Postgres db is connected");
    Ok(db)
}