using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using StellaOps.Feedser.Models;
using Xunit;

namespace StellaOps.Feedser.Models.Tests;

public sealed class SerializationDeterminismTests
{
    private static readonly string[] Cultures =
    {
        "en-US",
        "fr-FR",
        "tr-TR",
        "ja-JP",
        "ar-SA"
    };

    [Fact]
    public void CanonicalSerializer_ProducesStableJsonAcrossCultures()
    {
        var examples = CanonicalExampleFactory.GetExamples().ToArray();
        var baseline = SerializeUnderCulture(CultureInfo.InvariantCulture, examples);

        foreach (var cultureName in Cultures)
        {
            var culture = CultureInfo.GetCultureInfo(cultureName);
            var serialized = SerializeUnderCulture(culture, examples);

            Assert.Equal(baseline.Count, serialized.Count);
            for (var i = 0; i < baseline.Count; i++)
            {
                Assert.Equal(baseline[i].Compact, serialized[i].Compact);
                Assert.Equal(baseline[i].Indented, serialized[i].Indented);
            }
        }
    }

    private static List<(string Name, string Compact, string Indented)> SerializeUnderCulture(
        CultureInfo culture,
        IReadOnlyList<(string Name, Advisory Advisory)> examples)
    {
        var originalCulture = CultureInfo.CurrentCulture;
        var originalUiCulture = CultureInfo.CurrentUICulture;
        try
        {
            CultureInfo.CurrentCulture = culture;
            CultureInfo.CurrentUICulture = culture;

            var results = new List<(string Name, string Compact, string Indented)>(examples.Count);
            foreach (var (name, advisory) in examples)
            {
                var compact = CanonicalJsonSerializer.Serialize(advisory);
                var indented = CanonicalJsonSerializer.SerializeIndented(advisory);
                results.Add((name, compact, indented));
            }

            return results;
        }
        finally
        {
            CultureInfo.CurrentCulture = originalCulture;
            CultureInfo.CurrentUICulture = originalUiCulture;
        }
    }
}
