using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using Core.Abstractions;

namespace DataProviders.Converters {

  public class EnumerationSerializer<T> : IBsonSerializer<T> where T : Enumeration {

    private T Deserialize(IBsonReader reader) => Enumeration.FromValue<T>(BsonSerializer.Deserialize<int>(reader));
    private void Serialize(IBsonWriter writer, T value) => BsonSerializer.Serialize(writer, value.Id);

    public Type ValueType { get => typeof(T); }

    public T Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) =>
      Deserialize(context.Reader);

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, T value) =>
      Serialize(context.Writer, value);

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) =>
      Serialize(context.Writer, (T)value);

    object IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) =>
      Deserialize(context.Reader);
  }
}
