using GerbilManagerWebAPI.Endpoints;

namespace GerbilManager.Tests;

/// <summary>WEB-2: POST /api/publish — atomic swap, file layout, staging cleanup.</summary>
public class CmsPublishTests
{
    private static string TempRoot() =>
        Path.Combine(Path.GetTempPath(), "gm-publish-test-" + Guid.NewGuid().ToString("N"));

    [Fact]
    public async Task Publish_erstellt_live_Verzeichnis_mit_allen_Dateien()
    {
        var root = TempRoot();
        try
        {
            var files = new Dictionary<string, string>
            {
                ["index.html"]        = "<html>start</html>",
                ["kontakt/index.html"] = "<html>kontakt</html>",
                ["assets/site.css"]   = "body {}",
            };

            await CmsEndpoints.PublishToDirectoryAsync(files, root);

            Assert.True(File.Exists(Path.Combine(root, "live", "index.html")));
            Assert.True(File.Exists(Path.Combine(root, "live", "kontakt", "index.html")));
            Assert.True(File.Exists(Path.Combine(root, "live", "assets", "site.css")));
            Assert.Equal("<html>start</html>",
                await File.ReadAllTextAsync(Path.Combine(root, "live", "index.html")));
        }
        finally { if (Directory.Exists(root)) Directory.Delete(root, true); }
    }

    [Fact]
    public async Task Publish_atomarer_Swap_ueberschreibt_alte_live_Version()
    {
        var root = TempRoot();
        try
        {
            await CmsEndpoints.PublishToDirectoryAsync(
                new Dictionary<string, string> { ["index.html"] = "version-1" }, root);

            await CmsEndpoints.PublishToDirectoryAsync(
                new Dictionary<string, string> { ["index.html"] = "version-2" }, root);

            var content = await File.ReadAllTextAsync(Path.Combine(root, "live", "index.html"));
            Assert.Equal("version-2", content);
        }
        finally { if (Directory.Exists(root)) Directory.Delete(root, true); }
    }

    [Fact]
    public async Task Publish_kein_staging_oder_old_Verzeichnis_nach_Swap()
    {
        var root = TempRoot();
        try
        {
            await CmsEndpoints.PublishToDirectoryAsync(
                new Dictionary<string, string> { ["index.html"] = "x" }, root);

            Assert.False(Directory.Exists(Path.Combine(root, "_staging_new")));
            Assert.False(Directory.Exists(Path.Combine(root, "_old")));
        }
        finally { if (Directory.Exists(root)) Directory.Delete(root, true); }
    }

    [Fact]
    public async Task Publish_mehrfach_ohne_Fehler()
    {
        var root = TempRoot();
        try
        {
            for (int i = 1; i <= 3; i++)
            {
                await CmsEndpoints.PublishToDirectoryAsync(
                    new Dictionary<string, string> { ["index.html"] = $"v{i}" }, root);
            }

            Assert.Equal("v3",
                await File.ReadAllTextAsync(Path.Combine(root, "live", "index.html")));
        }
        finally { if (Directory.Exists(root)) Directory.Delete(root, true); }
    }

    [Fact]
    public async Task Publish_UTF8_Inhalt_korrekt_gespeichert()
    {
        var root = TempRoot();
        try
        {
            const string german = "<html>Züchter — Rennmäuse & mehr</html>";
            await CmsEndpoints.PublishToDirectoryAsync(
                new Dictionary<string, string> { ["index.html"] = german }, root);

            var content = await File.ReadAllTextAsync(
                Path.Combine(root, "live", "index.html"),
                System.Text.Encoding.UTF8);
            Assert.Equal(german, content);
        }
        finally { if (Directory.Exists(root)) Directory.Delete(root, true); }
    }
}
