using System.Text.Json;
using System.Text.Json.Serialization;

namespace ZB.MOM.NatsNet.Server;

internal static class ConsumerPolicyExtensions
{
    internal static string String(this PriorityPolicy policy) =>
        policy switch
        {
            PriorityPolicy.PriorityOverflow => "\"overflow\"",
            PriorityPolicy.PriorityPinnedClient => "\"pinned_client\"",
            PriorityPolicy.PriorityPrioritized => "\"prioritized\"",
            _ => "\"none\"",
        };

    internal static string String(this DeliverPolicy policy) =>
        policy switch
        {
            DeliverPolicy.DeliverAll => "all",
            DeliverPolicy.DeliverLast => "last",
            DeliverPolicy.DeliverNew => "new",
            DeliverPolicy.DeliverByStartSequence => "by_start_sequence",
            DeliverPolicy.DeliverByStartTime => "by_start_time",
            DeliverPolicy.DeliverLastPerSubject => "last_per_subject",
            _ => "undefined",
        };

    internal static string String(this AckPolicy policy) =>
        policy switch
        {
            AckPolicy.AckNone => "none",
            AckPolicy.AckAll => "all",
            _ => "explicit",
        };

    internal static string String(this ReplayPolicy policy) =>
        policy switch
        {
            ReplayPolicy.ReplayInstant => "instant",
            _ => "original",
        };
}

public sealed class PriorityPolicyJsonConverter : JsonConverter<PriorityPolicy>
{
    public override PriorityPolicy Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.String)
            throw new JsonException("can not unmarshal token");

        return reader.GetString() switch
        {
            "none" => PriorityPolicy.PriorityNone,
            "overflow" => PriorityPolicy.PriorityOverflow,
            "pinned_client" => PriorityPolicy.PriorityPinnedClient,
            "prioritized" => PriorityPolicy.PriorityPrioritized,
            var value => throw new JsonException($"unknown priority policy: {value}"),
        };
    }

    public override void Write(Utf8JsonWriter writer, PriorityPolicy value, JsonSerializerOptions options)
    {
        switch (value)
        {
            case PriorityPolicy.PriorityNone:
                writer.WriteStringValue("none");
                break;
            case PriorityPolicy.PriorityOverflow:
                writer.WriteStringValue("overflow");
                break;
            case PriorityPolicy.PriorityPinnedClient:
                writer.WriteStringValue("pinned_client");
                break;
            case PriorityPolicy.PriorityPrioritized:
                writer.WriteStringValue("prioritized");
                break;
            default:
                throw new JsonException($"unknown priority policy: {value}");
        }
    }
}
