using System.Reflection;
using adas_core.Domain.Models;
using MongoDB.Bson.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
namespace adas_core.Infrastructure.Utils;
///
/// Provides conversion logic for values, supporting JSON serialization through and BSON serialization through .
///
///
/// The optional constructor parameter specifies the target value type used during conversion.
///
public class PatientObservationConverter(Type? valueType) : JsonConverter, IBsonSerializer
{
///
/// Deserializes a BSON value using the provided deserialization context and arguments.
///
/// The deserialization context that provides the BSON reader and configuration.
/// The deserialization arguments containing additional information for the operation.
/// An object representing the deserialized value.
/// Always thrown because the method is not yet implemented.
public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
throw new NotImplementedException();
}
///
/// Serializes the specified value into a BSON format using the provided serialization context and arguments. This implementation is not yet provided and currently throws a .
///
/// The BSON serialization context that provides access to the writer and configuration used during serialization.
/// The BSON serialization arguments containing additional information that may influence the serialization process.
/// The object to be serialized into BSON.
/// Thrown because the serialization logic has not been implemented.
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
{
throw new NotImplementedException();
}
public Type? ValueType { get; } = valueType;
///
/// Serializes a instance to JSON, applying a string enum converter to the Status property and excluding the MessageTime property from the output. If the supplied value is null, nothing is written to the .
///
/// The JSON writer that receives the serialized output.
/// The patient observation to serialize. When null, the method performs no serialization.
/// The JSON serializer used during the conversion process.
public override void WriteJson(JsonWriter writer, PatientObservation? value, JsonSerializer serializer)
{
if (value != null)
{
var jo = JObject.FromObject(value);
// Add [JsonConverter(typeof(StringEnumConverter))] attribute to specified properties
AddStringEnumConverterAttribute(value, "Status");
jo.Property("MessageTime")?.Remove();
jo.WriteTo(writer);
}
}
///
/// Adds a JsonConverterAttribute for StringEnumConverter to the specified property if one is not already present. If the property cannot be found on the object's type, the method does nothing.
///
/// The object instance whose property should be annotated.
/// The name of the property to which the StringEnumConverter attribute should 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);
}
}
}
///
/// Deserializes a JSON representation into a instance.
///
/// The to read the JSON from.
/// The type of the object being deserialized.
/// The existing value of the object to populate, or if none.
/// Indicates whether contains a value to reuse.
/// The used to read nested values.
/// A instance produced from the JSON.
/// Thrown because the method has not been implemented yet.
public override PatientObservation ReadJson(JsonReader reader, Type objectType, PatientObservation? existingValue,
bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}