using System.Collections.Generic;
using System.Collections.Immutable;
using CSharpFunctionalExtensions;
public static void Main()
List<string> AvailableAddr = ["1", "2", "3", "4"];
Console.WriteLine(AvailableAddr.RandomSubset(1).First());
RECEIVE_RESPONSE_REQUIRED,
static public class Extensions
static public string ToStr(this Header _H) => _H switch
Header.SENDER_ADDRESS => "SENDER_ADDRESS",
Header.DESTINATION_ADDRESS => "DESTINATION_ADDRESS",
Header.ENCODING => "ENCODING",
Header.PRIORITY => "PRIORITY",
Header.CREATION_TIME => "CREATION_TIME",
Header.LIFESPAN => "LIFESPAN",
Header.RECEIVE_RESPONSE_REQUIRED => "RECEIVE_RESPONSE_REQUIRED",
Header.MESSAGE_SIZE => "MESSAGE_SIZE",
Header.MAX_MESSAGE_SIZE => "MAX_MESSAGE_SIZE",
Header.TOTAL_SIZE => "TOTAL_SIZE",
_ => throw new ArgumentOutOfRangeException(nameof(_H), _H, null)};
static public string ToBase64(this Guid _UUID)
return Convert.ToBase64String(_UUID.ToByteArray());
public const string DEFAULT_VAL = "DEFAULT";
static readonly private ImmutableDictionary<string, string> DEFAULT_HEADERS = ImmutableDictionary.CreateRange([new KeyValuePair<string, string>("ID", "000000"), new KeyValuePair<string, string>("SENDER_ADDRESS", DEFAULT_VAL), new KeyValuePair<string, string>("DESTINATION_ADDRESS", DEFAULT_VAL), new KeyValuePair<string, string>("TYPE", DEFAULT_VAL), new KeyValuePair<string, string>("ENCODING", "utf-8"), new KeyValuePair<string, string>("INDEX", "-1"), new KeyValuePair<string, string>("PRIORITY", "20"), new KeyValuePair<string, string>("CREATION_TIME", DateTime.MinValue.ToBinary().ToString()), new KeyValuePair<string, string>("LIFESPAN", "60000"), new KeyValuePair<string, string>("HOPS", "0"), new KeyValuePair<string, string>("RECEIVE_RESPONSE_REQUIRED", "NO"), new KeyValuePair<string, string>("MESSAGE_SIZE", "0"), new KeyValuePair<string, string>("MAX_MESSAGE_SIZE", "1000"), new KeyValuePair<string, string>("TOTAL_SIZE", "-1")]);
private Dictionary<string, string> IntHeaders;
IntHeaders = DEFAULT_HEADERS.ToDictionary();
public Headers(Dictionary<string, string> Metadata)
IntHeaders = DEFAULT_HEADERS.ToDictionary();
foreach (KeyValuePair<string, string> KVP in Metadata)
IntHeaders.TryAdd(KVP.Key, KVP.Value);
private void ResetHeaders()
IntHeaders = DEFAULT_HEADERS.ToDictionary();
public string GetHeader(Header _H)
return IntHeaders[_H.ToStr()];
public void SetHeaderValue(Header _H, string _Value)
IntHeaders[_H.ToStr()] = _Value;
public void SetMetadata(string _Header, string _Value)
if (!IntHeaders.TryAdd(_Header, _Value))
IntHeaders.Add(_Header, _Value);
public Maybe<string> GetMetadata(string _Header)
return IntHeaders.TryGetValue(_Header, out string Value) ? Value : Maybe.None;
private Headers IntHeaders = new Headers();
public string ID { get => IntHeaders.GetHeader(Header.ID); set => IntHeaders.SetHeaderValue(Header.ID, value); }
public string SenderAddress { get => IntHeaders.GetHeader(Header.SENDER_ADDRESS); set => IntHeaders.SetHeaderValue(Header.SENDER_ADDRESS, value); }
public string DestinationAddress { get => IntHeaders.GetHeader(Header.DESTINATION_ADDRESS); set => IntHeaders.SetHeaderValue(Header.DESTINATION_ADDRESS, value); }
public string MessageType { get => IntHeaders.GetHeader(Header.TYPE); set => IntHeaders.SetHeaderValue(Header.TYPE, value); }
public Encoding MessageEncoding { get => Encoding.GetEncoding(IntHeaders.GetHeader(Header.ENCODING)); set => IntHeaders.SetHeaderValue(Header.ENCODING, value.WebName); }
public int Index { get => Convert.ToInt32(IntHeaders.GetHeader(Header.INDEX)); set => IntHeaders.SetHeaderValue(Header.INDEX, value.ToString()); }
public int Priority { get => Convert.ToInt32(IntHeaders.GetHeader(Header.PRIORITY)); set => IntHeaders.SetHeaderValue(Header.PRIORITY, value.ToString()); }
public DateTime CreationTime { get => DateTime.FromBinary(Convert.ToInt64(IntHeaders.GetHeader(Header.CREATION_TIME))); set => IntHeaders.SetHeaderValue(Header.CREATION_TIME, value.ToBinary().ToString()); }
public TimeSpan Lifespan { get => TimeSpan.FromMilliseconds(Convert.ToInt64(IntHeaders.GetHeader(Header.LIFESPAN))); set => IntHeaders.SetHeaderValue(Header.LIFESPAN, value.TotalMilliseconds.ToString()); }
public int Hops { get => Convert.ToInt32(IntHeaders.GetHeader(Header.HOPS)); set => IntHeaders.SetHeaderValue(Header.HOPS, value.ToString()); }
public bool ResponseRequired { get => Convert.ToBoolean(IntHeaders.GetHeader(Header.RECEIVE_RESPONSE_REQUIRED)); set => IntHeaders.SetHeaderValue(Header.RECEIVE_RESPONSE_REQUIRED, value.ToString()); }
public int MessageSize { get => Convert.ToInt32(IntHeaders.GetHeader(Header.MESSAGE_SIZE)); set => IntHeaders.SetHeaderValue(Header.MESSAGE_SIZE, value.ToString()); }
public int MaxMessageSize { get => Convert.ToInt32(IntHeaders.GetHeader(Header.MAX_MESSAGE_SIZE)); set => IntHeaders.SetHeaderValue(Header.MAX_MESSAGE_SIZE, value.ToString()); }
public long TotalSize { get => Convert.ToInt64(IntHeaders.GetHeader(Header.TOTAL_SIZE)); set => IntHeaders.SetHeaderValue(Header.TOTAL_SIZE, value.ToString()); }
public Message(string _SenderAddress, string _DestinationAddress, string? _Payload = null)
SenderAddress = _SenderAddress;
DestinationAddress = _DestinationAddress;
CreationTime = DateTime.Now;
ID = Guid.CreateVersion7().ToBase64();
if (_Payload is not null)
private Maybe<string> _Payload = string.Empty;
public Maybe<string> Payload
int Size = SizeInBytes(value.Value);
if (SenderAddress == Headers.DEFAULT_VAL || DestinationAddress == Headers.DEFAULT_VAL || CreationTime == DateTime.MinValue)
if (MessageSize != SizeInBytes(Payload.Value))
private int SizeInBytes(string _Value) => MessageEncoding.GetByteCount(_Value);
return new Message(SenderAddress, DestinationAddress, Payload.GetValueOrDefault())
CreationTime = CreationTime,
MessageEncoding = MessageEncoding,
MessageSize = MessageSize,
MessageType = MessageType,
ResponseRequired = ResponseRequired,
MaxMessageSize = MaxMessageSize,
public override string ToString() {
return $"[ID: {ID}],[Sender Addr: {SenderAddress}],[Destination Addr: {DestinationAddress}]," +
$"[Type: {MessageType}],[Encoding: {MessageEncoding}],[Index: {Index}]," +
$"[Priority: {Priority}],[Creation Time: {CreationTime}],[Lifespan: {Lifespan}]," +
$"[Hops: {Hops}],[Response Req: {ResponseRequired}],[Size: {MessageSize}]," +
$"[Max Size: {MaxMessageSize}],[Total Size: {TotalSize}]\n[Payload: {Payload}]";