// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use serde::{Deserialize, Serialize};

/// The response message for a getConnectedFullNodes request.
/// Returns the pubkeys of the nodes connected to the validator
/// or full node and how long they have been connected in milliseconds.
#[derive(Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct GetConnectedFullNodesResponse {
    /// The full nodes' pubkeys and how long they have been connected
    pub pubkeys_and_millis: Vec<(String, u128)>,
}

impl GetConnectedFullNodesResponse {
    pub fn new(pubkeys_and_millis: Vec<(String, u128)>) -> Self {
        Self { pubkeys_and_millis }
    }
}

/// Request for getConnectedFullNodes RPC call
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct GetConnectedFullNodesRequest {
    #[serde(default)]
    pub version: u16,
}

impl GetConnectedFullNodesRequest {
    pub fn new() -> Self {
        Self { version: 0 }
    }
}

impl Default for GetConnectedFullNodesRequest {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use serde_json::{from_str, to_string};

    use super::*;

    #[test]
    fn test_get_connected_full_nodes_response_empty_serialization() {
        let pubkeys_and_millis = vec![];
        let response = GetConnectedFullNodesResponse::new(pubkeys_and_millis.clone());
        let json = to_string(&response).unwrap();
        assert_eq!(json, "[]");

        let deserialized: GetConnectedFullNodesResponse = from_str(&json).unwrap();
        assert_eq!(deserialized.pubkeys_and_millis, pubkeys_and_millis);
    }

    #[test]
    fn test_get_connected_full_node_response_non_empty_serialization() {
        let pubkeys_and_millis = vec![("1".to_string(), 1u128), ("2".to_string(), 2u128)];
        let response = GetConnectedFullNodesResponse::new(pubkeys_and_millis.clone());
        let json = to_string(&response).unwrap();
        assert_eq!(json, "[[\"1\",1],[\"2\",2]]");

        let deserialized: GetConnectedFullNodesResponse = from_str(&json).unwrap();
        assert_eq!(deserialized.pubkeys_and_millis, pubkeys_and_millis);
    }
}
