//! Scylla backend implementation.
use crate::client::backend::{
    BackendError, BackendResult, BackendType, DatabaseBackend, HealthStatus, QueryLanguage,
    QueryResult, TranslatedQuery,
};
use crate::drivers::scylla::client as scylla_client;
use crate::drivers::scylla::client::ScyllaConnectionInfo;
use crate::drivers::scylla::health;
use async_trait::async_trait;

pub struct ScyllaBackend {
    info: ScyllaConnectionInfo,
}

impl ScyllaBackend {
    pub fn new(info: ScyllaConnectionInfo) -> Self {
        Self { info }
    }
}

#[async_trait]
impl DatabaseBackend for ScyllaBackend {
    async fn execute_query(&self, query: TranslatedQuery) -> BackendResult<QueryResult> {
        if !matches!(query.language, QueryLanguage::Cql) {
            return Err(BackendError::Generic(
                "Scylla backend only supports CQL".to_string(),
            ));
        }

        let (rows, columns) = scylla_client::execute_query(query.sql)
            .await
            .map_err(|err| BackendError::Generic(err.to_string()))?;

        Ok(QueryResult::new(rows, columns))
    }

    async fn health_check(&self) -> BackendResult<HealthStatus> {
        let tracker = health::global_tracker();

        if let Some(deadline) = tracker.offline_until(&self.info.host) {
            return Ok(HealthStatus::Offline(deadline));
        }

        Ok(HealthStatus::Healthy)
    }

    fn backend_type(&self) -> BackendType {
        BackendType::Scylla
    }

    fn supports_sql(&self) -> bool {
        false
    }

    fn supports_cql(&self) -> bool {
        true
    }
}
