using Google.Protobuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Tango.PMR.Common;
namespace Tango.PMR
{
///
/// Contains helper class for encoding and decoding PMR messages.
///
public static class MessageFactory
{
private static Dictionary _pmrTypes;
private static MethodInfo _parseTangoMessageMethod;
static MessageFactory()
{
_parseTangoMessageMethod = typeof(MessageFactory).GetMethod("ParseTangoMessage", BindingFlags.Public | BindingFlags.Static);
_pmrTypes = new Dictionary();
var types = typeof(MessageFactory).Assembly.GetTypes().ToList();
foreach (var value in Enum.GetValues(typeof(MessageType)).OfType())
{
var type = types.SingleOrDefault(x => x.Name == value.ToOriginalName());
if (type != null)
{
_pmrTypes.Add(value, type);
}
}
}
///
/// Creates a new .
///
///
///
public static TangoMessage CreateTangoMessage() where T : IMessage
{
TangoMessage tango = new TangoMessage(Activator.CreateInstance(), ParseMessageType(typeof(T).Name));
return tango;
}
///
/// Creates a new .
///
///
///
public static TangoMessage CreateTangoMessage(T message) where T : IMessage
{
TangoMessage tango = CreateTangoMessage();
tango.Message = message;
return tango;
}
///
/// Creates a new .
///
///
///
public static TangoMessage CreateTangoMessage(String token) where T : IMessage
{
TangoMessage tango = CreateTangoMessage();
tango.Container.Token = token;
return tango;
}
///
/// Creates a new .
///
///
///
public static TangoMessage CreateTangoMessage(T message, String token) where T : IMessage
{
TangoMessage tango = CreateTangoMessage(token);
tango.Message = message;
return tango;
}
///
/// Parses the specified tango message type from the specified byte array.
///
///
/// The data.
///
public static TangoMessage ParseTangoMessage(byte[] data) where T : IMessage
{
MessageContainer container = MessageContainer.Parser.ParseFrom(data);
MessageParser parser = new MessageParser(() => Activator.CreateInstance());
TangoMessage tango = new TangoMessage(parser.ParseFrom(container.Data), container.Type);
return tango;
}
///
/// Parses the specified tango message type from the specified message container.
///
///
/// The data.
///
public static TangoMessage ParseTangoMessageFromContainer(MessageContainer container) where T : IMessage
{
MessageParser parser = new MessageParser(() => Activator.CreateInstance());
TangoMessage tango = new TangoMessage(parser.ParseFrom(container.Data), container.Type);
tango.Container = container;
return tango;
}
///
/// Parses an unknown tango message from the specified byte array.
///
/// The data.
///
public static ITangoMessage ParseTangoMessageAgnostic(byte[] data)
{
MessageContainer container = MessageContainer.Parser.ParseFrom(data);
IMessage message = ExtractMessageFromContainer(container);
return (ITangoMessage)_parseTangoMessageMethod.MakeGenericMethod(message.GetType()).Invoke(null, new[] { data });
}
///
/// Parses the message from the specified container.
///
///
/// The container.
///
public static T ExtractMessageFromContainer(MessageContainer container) where T : IMessage
{
MessageParser parser = new MessageParser(() => Activator.CreateInstance());
return parser.ParseFrom(container.Data);
}
///
/// Parses the message from the specified container.
///
///
/// The container.
///
public static IMessage ExtractMessageFromContainer(MessageContainer container)
{
var type = _pmrTypes[container.Type];
MessageParser parser = type.GetProperty("Parser").GetValue(container) as MessageParser;
return parser.ParseFrom(container.Data);
}
///
/// Parses a message container from the specified byte array.
///
/// The data.
///
public static MessageContainer ParseContainer(byte[] data)
{
MessageContainer container = MessageContainer.Parser.ParseFrom(data);
return container;
}
///
/// Parses a message container from the specified byte array containing JSON data.
///
/// The data.
///
public static MessageContainer ParseContainerJson(byte[] data)
{
MessageContainer container = MessageContainer.Parser.ParseJson(Encoding.UTF8.GetString(data));
return container;
}
///
/// Parses the specified text to a PMR .
///
/// The text.
///
/// Could not parse message type " + text
public static MessageType ParseMessageType(String text)
{
MessageType t;
if (Enum.TryParse(text, true, out t))
{
return t;
}
else
{
throw new InvalidCastException("Message type " + text + " was not found on PMR MessageType enumeration!");
}
}
}
}