use config::AppConfig;
use db::cache::AppCache;
use db::database::AppDatabase;
use deadpool_redis::cluster::Pool as RedisPool;
use slog::Logger;
use std::sync::Arc;

use crate::hook::pool::GitHookPool;

#[derive(Clone)]
pub struct GitServiceHooks {
    pub(crate) db: AppDatabase,
    pub(crate) cache: AppCache,
    pub(crate) redis_pool: RedisPool,
    pub(crate) logger: Logger,
    pub(crate) config: AppConfig,
    pub(crate) http: Arc<reqwest::Client>,
}

impl GitServiceHooks {
    pub fn new(
        db: AppDatabase,
        cache: AppCache,
        redis_pool: RedisPool,
        logger: Logger,
        config: AppConfig,
        http: Arc<reqwest::Client>,
    ) -> Self {
        Self {
            db,
            cache,
            redis_pool,
            logger,
            config,
            http,
        }
    }

    pub async fn run(
        self,
        cancel: tokio_util::sync::CancellationToken,
    ) -> Result<(), crate::GitError> {
        let pool_config = config::hook::PoolConfig::from_env(&self.config);

        let pool = GitHookPool::new(
            pool_config,
            self.db,
            self.cache,
            self.redis_pool,
            self.logger.clone(),
            self.http,
        )
        .await?;

        let pool_arc = Arc::new(pool);

        slog::info!(self.logger, "git hook service started");

        pool_arc.run(cancel).await;

        slog::info!(self.logger, "git hook service stopped");

        Ok(())
    }
}

pub mod event;
pub mod pool;
pub mod sync;
pub mod webhook_dispatch;
