using System.Text;
using StellaOps.Feedser.Models;

namespace StellaOps.Feedser.Models.Tests;

public sealed class CanonicalExamplesTests
{
    private static readonly string FixtureRoot = Path.Combine(GetProjectRoot(), "Fixtures");
    private const string UpdateEnvVar = "UPDATE_GOLDENS";

    [Trait("Category", "GoldenSnapshots")]
    [Fact]
    public void CanonicalExamplesMatchGoldenSnapshots()
    {
        Directory.CreateDirectory(FixtureRoot);
        var envValue = Environment.GetEnvironmentVariable(UpdateEnvVar);
        var updateGoldens = string.Equals(envValue, "1", StringComparison.OrdinalIgnoreCase);
        var failures = new List<string>();

        foreach (var (name, advisory) in CanonicalExampleFactory.GetExamples())
        {
            var snapshot = SnapshotSerializer.ToSnapshot(advisory).Replace("\r\n", "\n");
            var fixturePath = Path.Combine(FixtureRoot, $"{name}.json");

            if (updateGoldens)
            {
                File.WriteAllText(fixturePath, snapshot);
                continue;
            }

            if (!File.Exists(fixturePath))
            {
                failures.Add($"Missing golden fixture: {fixturePath}. Set {UpdateEnvVar}=1 to generate.");
                continue;
            }

            var expected = File.ReadAllText(fixturePath).Replace("\r\n", "\n");
            if (!string.Equals(expected, snapshot, StringComparison.Ordinal))
            {
                var actualPath = Path.Combine(FixtureRoot, $"{name}.actual.json");
                File.WriteAllText(actualPath, snapshot);
                failures.Add($"Fixture mismatch for {name}. Set {UpdateEnvVar}=1 to regenerate.");
            }
        }

        if (failures.Count > 0)
        {
            var builder = new StringBuilder();
            foreach (var failure in failures)
            {
                builder.AppendLine(failure);
            }

            Assert.Fail(builder.ToString());
        }
    }

    private static string GetProjectRoot()
        => Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", ".."));
}
