using System.Reflection;
using adas_core.Domain.Models;
using adas_core.Domain.Models.Pumps;
using MongoDB.Bson.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using JsonConverterAttribute = Newtonsoft.Json.JsonConverterAttribute;
namespace adas_core.Infrastructure.Utils;
///
/// Provides JSON conversion for instances and supports BSON serialization through the interface.
///
public class PatientPumpObservationConverter : JsonConverter, IBsonSerializer
{
///
/// Deserializes a BSON value into a .NET object using the provided deserialization context and arguments.
///
/// The BSON deserialization context that provides access to the reader and configuration.
/// The deserialization arguments containing additional settings for the operation.
/// The deserialized object.
/// Thrown when the method is invoked, as the deserialization logic has not been implemented.
public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
throw new NotImplementedException();
}
///
/// Serializes the specified value into BSON format using the provided serialization context and arguments.
/// This method is not yet implemented and currently throws an exception when invoked.
///
/// The BSON serialization context that provides the writer and configuration for the operation.
/// The BSON serialization arguments that influence the serialization behavior.
/// The object to be serialized into BSON.
/// Thrown because the method has not been implemented.
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
{
throw new NotImplementedException();
}
public Type ValueType => typeof(PatientObservationAlarm);
///
/// Deserializes a JSON representation into a instance.
/// This implementation is not yet provided and always throws an exception.
///
/// The to read JSON from.
/// The type of the object to deserialize.
/// The existing value of the object being read, or null if there is no existing value.
/// A value indicating whether has a value.
/// The used for deserialization.
/// A instance reconstructed from the JSON data.
/// Thrown because the method has not been implemented yet.
public override PumpObservation ReadJson(JsonReader reader, Type objectType,
PumpObservation? existingValue,
bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
///
/// Serializes the specified value to JSON, applying string enum conversion to the Event, Status, PumpMode, InfusingStatus, and AlarmMode properties. No output is written when the value is null.
///
/// The JSON writer to which the serialized object is written.
/// The object to serialize; if null, the method does nothing.
/// The JSON serializer used as context for the conversion.
public new void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value != null)
{
var jo = JObject.FromObject(value);
// Add [JsonConverter(typeof(StringEnumConverter))] attribute to specified properties
AddStringEnumConverterAttribute(value, "Event");
AddStringEnumConverterAttribute(value, "Status");
AddStringEnumConverterAttribute(value, "PumpMode");
AddStringEnumConverterAttribute(value, "InfusingStatus");
AddStringEnumConverterAttribute(value, "AlarmMode");
jo.WriteTo(writer);
}
}
///
/// Serializes a instance to JSON. This override is not yet implemented and will always throw.
///
/// The JSON writer used to emit the serialized output.
/// The to serialize, or if no value is available.
/// The providing serialization context and options.
/// Always thrown because the method has not been implemented.
public override void WriteJson(JsonWriter writer, PumpObservation? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
///
/// Adds a of type to the specified property, ensuring that enum values are serialized as their string names rather than numeric values. If the property already has a applied, no changes are made.
///
/// The object instance whose property will be inspected for the attribute.
/// The name of the property to which the converter attribute will be added.
private static void AddStringEnumConverterAttribute(object value, string propertyName)
{
var prop = value.GetType().GetProperty(propertyName);
var attr = new JsonConverterAttribute(typeof(StringEnumConverter));
if (prop != null)
{
var attrs = prop.GetCustomAttributes(false);
// Check if the attribute is not already applied
if (Array.Find(attrs, a => a is JsonConverterAttribute) == null)
{
// Create a new array that includes the existing attributes and the new one
var newAttrs = new object[attrs.Length + 1];
Array.Copy(attrs, newAttrs, attrs.Length);
newAttrs[attrs.Length] = attr;
// Use reflection to set the new attributes array
var field = typeof(PropertyInfo).GetField("m_customAttributes",
BindingFlags.Instance | BindingFlags.NonPublic);
field?.SetValue(prop, newAttrs);
}
}
}
}
/*How to use it:
BsonSerializer.RegisterSerializer(new PatientObservationAlarmConverter());
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Converters = { new PatientObservationAlarmConverter() }
};
*/