//! ## Cache hydration
//!
//! This module provides functionality to hydrate the application's shared cache with JSON data.
//! It includes a function to insert JSON data into the cache and return the same data.

use crate::AppState;
use actix_web::web::Data;
use serde_json::Value;
// no-op: keep imports minimal here
use crate::utils::redis_client::GLOBAL_REDIS;

/// Hydrates the cache with the provided JSON body and returns the JSON body.
///
/// # Arguments
///
/// * `app_state` - A `Data<AppState>` representing the shared application state with caches.
/// * `cache_key` - A `String` that serves as the key for storing the JSON body in the cache.
/// * `json_body` - A `Vec<Value>` containing the JSON data to be cached.
///
/// # Returns
///
/// * `Vec<Value>` - The same JSON body that was provided as input.
///
/// # Example
///
/// ```rust,no_run
/// # use actix_web::web::Data;
/// # use athena_rs::api::cache::hydrate::hydrate_cache_and_return_json;
/// # use athena_rs::AppState;
/// # use athena_rs::drivers::postgresql::sqlx_driver::PostgresClientRegistry;
/// # use moka::future::Cache;
/// # use reqwest::Client;
/// # use serde_json::json;
/// # use std::sync::Arc;
/// # use std::time::Instant;
/// # async fn doc_example() {
/// #     let cache: Cache<String, serde_json::Value> = Cache::builder().build();
/// #     let immortal: Cache<String, serde_json::Value> = Cache::builder().build();
/// #     let jdbc_pool_cache = Arc::new(Cache::builder().max_capacity(64).build());
/// #     let app_state = AppState {
/// #         cache: Arc::new(cache),
/// #         immortal_cache: Arc::new(immortal),
/// #         client: Client::new(),
/// #         process_start_time_seconds: 0,
/// #         process_started_at: Instant::now(),
/// #         pg_registry: Arc::new(PostgresClientRegistry::empty()),
/// #         jdbc_pool_cache,
/// #         gateway_force_camel_case_to_snake_case: false,
/// #         gateway_auto_cast_uuid_filter_values_to_text: true,
/// #         pipeline_registry: None,
/// #         logging_client_name: None,
/// #         gateway_auth_client_name: None,
/// #         gateway_jdbc_allow_private_hosts: false,
/// #         gateway_jdbc_allowed_hosts: Vec::new(),
/// #         prometheus_metrics_enabled: false,
/// #         metrics_state: Arc::new(athena_rs::api::metrics::MetricsState::new()),
/// #     };
/// #     let app_state = Data::new(app_state);
/// let cache_key = String::from("my_cache_key");
/// let json_body = vec![json!(1), json!(2), json!(3)];
/// let result = hydrate_cache_and_return_json(app_state, cache_key, json_body).await;
/// assert_eq!(result, vec![json!(1), json!(2), json!(3)]);
/// # }
/// ```
pub async fn hydrate_cache_and_return_json(
    app_state: Data<AppState>,
    cache_key: String,
    json_body: Vec<Value>,
) -> Vec<Value> {
    // Store just the array payload in the cache to match consumers' expectations
    let value_to_cache: Value = Value::Array(json_body.clone());
    app_state
        .cache
        .insert(cache_key.clone(), value_to_cache)
        .await;

    // Also write-through to Redis with a TTL that mirrors the in-memory cache TTL if desired
    if let Some(redis) = GLOBAL_REDIS.get() {
        let _ = redis
            .lock()
            .await
            .set_with_ttl(&cache_key, &Value::Array(json_body.clone()), 900u64)
            .await;
    }

    json_body
}
