// Bloom
//
// HTTP REST API caching middleware
// Copyright: 2017, Valerian Saliou <valerian@valeriansaliou.name>
// License: Mozilla Public License v2.0 (MPL v2.0)

use std::net::SocketAddr;

use super::defaults;
use super::env_var;

#[derive(Deserialize)]
pub struct Config {
    pub server: ConfigServer,
    pub control: ConfigControl,
    pub proxy: ConfigProxy,
    pub cache: ConfigCache,
    pub redis: ConfigRedis,
}

#[derive(Deserialize)]
pub struct ConfigServer {
    #[serde(
        default = "defaults::server_log_level",
        deserialize_with = "env_var::str"
    )]
    pub log_level: String,

    #[serde(
        default = "defaults::server_inet",
        deserialize_with = "env_var::socket_addr"
    )]
    pub inet: SocketAddr,
}

#[derive(Deserialize)]
pub struct ConfigControl {
    #[serde(
        default = "defaults::control_inet",
        deserialize_with = "env_var::socket_addr"
    )]
    pub inet: SocketAddr,

    #[serde(default = "defaults::control_tcp_timeout")]
    pub tcp_timeout: u64,
}

#[derive(Deserialize)]
pub struct ConfigProxy {
    #[serde(default = "defaults::proxy_shard_default")]
    pub shard_default: u8,

    pub shard: Vec<ConfigProxyShard>,
}

#[derive(Deserialize)]
pub struct ConfigProxyShard {
    #[serde(default = "defaults::proxy_shard_shard")]
    pub shard: u8,

    #[serde(
        default = "defaults::proxy_shard_host",
        deserialize_with = "env_var::str"
    )]
    pub host: String,

    #[serde(default = "defaults::proxy_shard_port")]
    pub port: u16,
}

#[derive(Deserialize)]
pub struct ConfigCache {
    #[serde(default = "defaults::cache_ttl_default")]
    pub ttl_default: usize,

    #[serde(
        default = "defaults::cache_disable_read",
        deserialize_with = "env_var::bool"
    )]
    pub disable_read: bool,

    #[serde(
        default = "defaults::cache_disable_write",
        deserialize_with = "env_var::bool"
    )]
    pub disable_write: bool,

    #[serde(
        default = "defaults::cache_compress_body",
        deserialize_with = "env_var::bool"
    )]
    pub compress_body: bool,

    #[serde(default = "defaults::cache_compress_level")]
    pub compress_level: i32,

    #[serde(default = "defaults::cache_compress_above_bytes")]
    pub compress_above_bytes: usize,
}

#[derive(Deserialize)]
pub struct ConfigRedis {
    #[serde(default = "defaults::redis_host", deserialize_with = "env_var::str")]
    pub host: String,

    #[serde(default = "defaults::redis_port")]
    pub port: u16,

    #[serde(default, deserialize_with = "env_var::opt_str")]
    pub password: Option<String>,

    #[serde(default = "defaults::redis_database")]
    pub database: u8,

    #[serde(default = "defaults::redis_connection_timeout_seconds")]
    pub connection_timeout_seconds: u64,

    #[serde(default = "defaults::redis_max_key_size")]
    pub max_key_size: usize,

    #[serde(default = "defaults::redis_max_key_expiration")]
    pub max_key_expiration: usize,
}
