1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use dotenv::dotenv;
use std::env;
use std::time::Duration;

/// Config for the Pusher client. We are defaulting to .env. 
/// TODO: look into .toml or .yaml
#[derive(Clone, Debug)]
pub struct PusherConfig {
    /// The Pusher App ID.
    pub app_id: String,

    /// The Pusher App key.
    pub app_key: String,

    /// The Pusher App secret.
    pub app_secret: String,

    /// The cluster.
    pub cluster: String,

    /// Whether to use TLS for connections. Defaults to true.
    pub use_tls: bool,

    /// The host to connect to. If None, the default Pusher host will be used.
    pub host: Option<String>,

    /// The maximum number of reconnection attempts. Defaults to 6.
    pub max_reconnection_attempts: u32,

    /// The backoff interval for reconnection attempts. Defaults to 1 second.
    pub backoff_interval: Duration,

    /// The activity timeout. Defaults to 120 seconds.
    pub activity_timeout: Duration,

    /// The pong timeout. Defaults to 30 seconds.
    pub pong_timeout: Duration,
}

impl Default for PusherConfig {
    fn default() -> Self {
        Self {
            app_id: String::new(),
            app_key: String::new(),
            app_secret: String::new(),
            cluster: String::new(),
            use_tls: false,
            host: None,
            max_reconnection_attempts: 6,
            backoff_interval: Duration::from_secs(1),
            activity_timeout: Duration::from_secs(120),
            pong_timeout: Duration::from_secs(30),
        }
    }
}

impl PusherConfig {
    pub fn from_env() -> Result<Self, env::VarError> {
        dotenv().ok(); // This line loads the .env file
        let cluster = env::var("PUSHER_CLUSTER").unwrap_or_else(|_| "mt1".to_string()); //Default to mt1.
        let host = env::var("PUSHER_HOST")
            .ok()
            .unwrap_or_else(|| format!("ws-{}.pusher.com", cluster)); // let's read <> build the host from the env variable

        Ok(Self {
            app_id: env::var("PUSHER_APP_ID")?,
            app_key: env::var("PUSHER_KEY")?,
            app_secret: env::var("PUSHER_SECRET")?,
            cluster,
            use_tls: env::var("PUSHER_USE_TLS")
                .map(|v| v.to_lowercase() == "true")
                .unwrap_or(true),
            host: Some(host),
            max_reconnection_attempts: env::var("PUSHER_MAX_RECONNECTION_ATTEMPTS")
                .ok()
                .and_then(|v| v.parse().ok())
                .unwrap_or(6),
            backoff_interval: Duration::from_secs(
                env::var("PUSHER_BACKOFF_INTERVAL")
                    .ok()
                    .and_then(|v| v.parse().ok())
                    .unwrap_or(1),
            ),
            activity_timeout: Duration::from_secs(
                env::var("PUSHER_ACTIVITY_TIMEOUT")
                    .ok()
                    .and_then(|v| v.parse().ok())
                    .unwrap_or(120),
            ),
            pong_timeout: Duration::from_secs(
                env::var("PUSHER_PONG_TIMEOUT")
                    .ok()
                    .and_then(|v| v.parse().ok())
                    .unwrap_or(30),
            ),
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_default_config() {
        let config = PusherConfig::default();
        // assert!(config.use_tls);
        assert_eq!(config.max_reconnection_attempts, 6);
        assert_eq!(config.backoff_interval, Duration::from_secs(1));
        assert_eq!(config.activity_timeout, Duration::from_secs(120));
        assert_eq!(config.pong_timeout, Duration::from_secs(30));
    }

    // #[test]
    // fn test_new_config() {
    //     let config =
    //         PusherConfig::from_env().expect("Failed to load Pusher configuration from environment");
    //     assert_eq!(config.app_id, "app_id");
    //     assert_eq!(config.app_key, "app_key");
    //     assert_eq!(config.app_secret, "app_secret");
    //     assert_eq!(config.cluster, "eu");
    // }
}