//! The wrapper for the server message to be transferred between client and server.
//!
//! # Notes
//! No unit testing has been assigned to this module as it is a simple wrapper around the server message. There
//! is no functionality to test.
use std::fmt::Debug;

use serde::{Deserialize, Serialize};

use super::interface::ServerMessage;

/// A server message wrapped in meta data around the message so the key value data can be processed and returned by the server.
///
/// # Fields
/// * `client_id`: the client ID for the allocator in the client to route back to the transacrtion actor in the client
/// * `server_id`: the server ID for the allocator in the server to route back to the transaction actor in the server
/// * `connection_id`: the connection ID for the connection that the message is being sent over (for logging)
/// * `transaction_id`: the transaction ID for the transaction that the message is being sent over (for logging)
/// * `message`: the server message to be sent between the client and the server that contains all data to perform a key value operation.
///              this will also contain the response from the key value operation
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct WrappedServerMessage {
	pub client_id: usize,         // allocator for the client
	pub server_id: Option<usize>, // allocator for the server
	pub connection_id: String, // this is for logging TODO => turn to essnetial and get it on the registration
	pub transaction_id: Option<String>,
	pub message: ServerMessage,
}

impl WrappedServerMessage {
	/// The constructor for the `WrappedServerMessage`.
	///
	/// # Arguments
	/// * `client_id`: the client ID for the allocator in the client to route back to the transacrtion actor in the client
	/// * `message`: the server message to be sent between the client and the server that contains all data to perform a key value operation.
	///             this will also contain the response from the key value operation
	/// * `connection_id`: the connection ID for the connection that the message is being sent over (for logging)
	///
	/// # Returns
	/// * `WrappedServerMessage`: the wrapped server message
	pub fn new(client_id: usize, message: ServerMessage, connection_id: String) -> Self {
		WrappedServerMessage {
			client_id,
			server_id: None,
			message,
			connection_id,
			transaction_id: None,
		}
	}

	/// Assigns a server ID to the wrapped server message.
	///
	/// # Arguments
	/// * `server_id`: the server ID for the allocator in the server to route back to the transaction actor in the server
	///
	/// # Returns
	/// * `WrappedServerMessage`: the wrapped server message with the server ID assigned to `self.server_id`
	pub fn server_id(mut self, server_id: usize) -> Self {
		self.server_id = Some(server_id);
		self
	}

	/// Assigns a transaction ID to the wrapped server message.
	///
	/// # Arguments
	/// * `transaction_id`: the transaction ID for the transaction that the message is being sent over (for logging)
	///
	/// # Returns
	/// * `WrappedServerMessage`: the wrapped server message with the transaction ID assigned to `self.transaction_id`
	pub fn transaction_id(mut self, transaction_id: String) -> Self {
		self.transaction_id = Some(transaction_id);
		self
	}
}
