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
use std::collections::HashSet;

use super::TransportConfig;
use crate::identity::SharedIdentity;

/// Ditto transport parameters / status
#[derive(Clone)]
pub(crate) struct SyncState {
    sync_active: bool,
    x509_valid: bool,
    web_valid: bool,
    identity: SharedIdentity,
    transport_config: TransportConfig,
}

impl SyncState {
    pub fn new(
        transport_config: TransportConfig,
        identity: SharedIdentity,
        web_valid: bool,
        x509_valid: bool,
    ) -> SyncState {
        SyncState {
            sync_active: false,
            web_valid,
            x509_valid,
            identity,
            transport_config,
        }
    }

    pub fn config(&self) -> &TransportConfig {
        &self.transport_config
    }

    pub fn set_config(&mut self, config: TransportConfig) -> &mut SyncState {
        self.transport_config = config;
        self
    }

    pub fn set_sync(&mut self, activated: bool) -> &mut SyncState {
        self.sync_active = activated;
        self
    }

    pub fn set_x509_valid(&mut self, valid: bool) -> &mut SyncState {
        self.x509_valid = valid;
        self
    }

    pub fn set_web_valid(&mut self, valid: bool) -> &mut SyncState {
        self.web_valid = valid;
        self
    }

    /// Compute effective state using Identity + other field + transport config
    pub fn compute_effective_state(&self) -> Self {
        let mut patched_config = self.transport_config.clone();
        if !self.sync_active || !self.x509_valid {
            patched_config.peer_to_peer.bluetooth_le.enabled = false;
            patched_config.peer_to_peer.lan.enabled = false;
            patched_config.listen.tcp.enabled = false;
            patched_config.connect.tcp_servers = HashSet::new();
        }

        if !self.sync_active || !self.web_valid {
            patched_config.connect.websocket_urls = HashSet::new();
        }

        if !self.sync_active {
            patched_config.listen.http.enabled = false;
        }

        if self.identity.is_cloud_sync_enabled() && self.sync_active && self.web_valid {
            let cloud_url = self
                .identity
                .sync_url()
                .expect("No cloud URL was provided in the Identity");
            patched_config.connect.websocket_urls.insert(cloud_url);
        }
        if patched_config.peer_to_peer.lan.enabled && !patched_config.listen.tcp.enabled {
            patched_config.listen.tcp.enabled = true;
            patched_config.listen.tcp.interface_ip = String::from("[::]");
            patched_config.listen.tcp.port = 0;
        }
        Self {
            transport_config: patched_config,
            ..self.clone()
        }
    }
}