using System.Text.Json;

namespace ZB.MOM.WW.MxGateway.Server.Security.Authentication;

public static class ApiKeyConstraintSerializer
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
        WriteIndented = false,
    };

    /// <summary>Serializes API key constraints to JSON, or returns null if the constraints are empty.</summary>
    /// <param name="constraints">The constraints to serialize.</param>
    /// <returns>The serialized JSON, or <see langword="null"/> when the constraints are empty.</returns>
    public static string? Serialize(ApiKeyConstraints constraints)
    {
        ArgumentNullException.ThrowIfNull(constraints);
        return constraints.IsEmpty ? null : JsonSerializer.Serialize(constraints, JsonOptions);
    }

    /// <summary>Deserializes API key constraints from JSON, or returns empty constraints if JSON is null or whitespace.</summary>
    /// <param name="json">The JSON string to deserialize.</param>
    /// <returns>The deserialized constraints, or <see cref="ApiKeyConstraints.Empty"/> when <paramref name="json"/> is null/whitespace.</returns>
    /// <remarks>
    ///     Members absent from the JSON take their default: rows persisted before
    ///     <see cref="ApiKeyConstraints.DashboardTags"/> existed carry no <c>dashboard_tags</c>
    ///     member and deserialize to an untagged key, unchanged in every other respect.
    /// </remarks>
    public static ApiKeyConstraints Deserialize(string? json)
    {
        if (string.IsNullOrWhiteSpace(json))
        {
            return ApiKeyConstraints.Empty;
        }

        return JsonSerializer.Deserialize<ApiKeyConstraints>(json, JsonOptions) ?? ApiKeyConstraints.Empty;
    }
}
