//! The interface for the server message.
use super::kv_operations::{
	MessageDel, MessageDelc, MessageDelr, MessageExists, MessageGet, MessageKeys, MessagePut,
	MessagePutc, MessageScan, MessageSet, ResponseGet, ResponseKeys, ResponseScan,
};
use nanoservices_utils::errors::NanoServiceError;
use serde::{Deserialize, Serialize};

/// The wrapper for different key value operations.
///
/// # Variants
/// * `Exists` - Check if a key exists.
/// * `Get` - Get the value of a key.
/// * `Set` - Set the value of a key.
/// * `Put` - Put a key value pair.
/// * `Putc` - Put a key value pair if the value of that key is the same as the one provided.
/// * `Del` - Delete a key.
/// * `Delc` - Delete a key if the value of that key is the same as the one provided.
/// * `Delr` - Delete a key and return the value.
/// * `Keys` - Get all keys within a range with a limit.
/// * `Scan` - Get all keys and values within a range with a limit.
/// * `EmptyCommit` - Commits the transaction without any more key value operations.
/// * `SetSavePoint` - Set a save point for the transaction.
/// * `RollbackToSavePoint` - Rollback to the last save point.
/// * `Rollback` - Rollback the transaction.
/// * `ResponseExists` - Response to the `Exists` operation.
/// * `ResponseGet` - Response to the `Get` operation.
/// * `ResponseKeys` - Response to the `Keys` operation.
/// * `ResponseScan` - Response to the `Scan` operation.
/// * `ResponseEmptyCommit` - Response to the `EmptyCommit` operation.
/// * `ResponseRolledBack` - Response to the `Rollback` operation.
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub enum ServerTransactionMessage {
	Exists(MessageExists),
	Get(MessageGet),
	Set(MessageSet),
	Put(MessagePut),
	Putc(MessagePutc),
	Del(MessageDel),
	Delc(MessageDelc),
	Delr(MessageDelr),
	Keys(MessageKeys),
	Scan(MessageScan),
	EmptyCommit,
	SetSavePoint,
	RollbackToSavePoint,
	ReleaseSavePoint,
	// Commit, this is commented out for now but if we need to add it back in, we can as we must
	// workout how to pass a generic message to the server under the `Commit` variant
	Rollback,
	EmptyResponse,
	ResponseExists(bool),
	ResponseGet(ResponseGet),
	ResponseKeys(ResponseKeys),
	ResponseScan(ResponseScan),
	ResponseEmptyCommit(bool),
	ResponseRolledBack(bool),
}

/// The wrapper for different server messages.
///
/// # Variants
/// * `BeginTransaction` - Begin a transaction creating a new transaction actor and setting the transaction id.
/// * `SendOperation` - Send a single operation to the transaction actor.
/// * `OneShotOperation` - Send a single operation to the transaction actor and commit it.
/// * `ChainedOperations` - Send a list of operations to the transaction actor.
/// * `CommitTransaction` - Commit the transaction.
/// * `Ping` - Ping the server.
/// * `Error` - An error message.
/// * `EmptyCommit` - Commits the transaction without any more key value operations.
/// * `RollbackTransaction` - Rollback the transaction.
/// * `Cleanup` - Cleanup the transaction removing all actors associated with the transaction being cleaned up.
/// * `CloseToNewTrancations` - Close the server or the connection to new transactions.
/// * `ClosedToNewTrancations` - Signals that the server or connection is now closed to new transactions.
/// * `SetSavePoint` - Set a save point for the transaction.
/// * `RollbackToSavePoint` - Rollback to the last save point.
/// * `ReleaseLastSavePoint` - Release the last save point (currently does nothing).
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub enum ServerMessage {
	BeginTransaction(ServerTransactionMessage),
	SendOperation(ServerTransactionMessage),
	OneShotOperation(ServerTransactionMessage),
	ChainedOperations(Vec<ServerTransactionMessage>),
	CommitTransaction(ServerTransactionMessage),
	Ping(usize),
	Error(NanoServiceError),
	// ones below have their own logging format with transaction_id
	EmptyCommit,
	RollbackTransaction,
	Cleanup,
	CloseToNewTrancations,
	ClosedToNewTrancations,
	// below is for savepoints for transactions
	SetSavePoint,
	RollbackToSavePoint,
	ReleaseLastSavePoint,
}
