using System.Reflection;
using Mbproxy.Admin;
using Shouldly;
using Xunit;

namespace Mbproxy.Tests.Admin;

/// <summary>
/// Guards the <c>Admin\wwwroot\*.*</c> embedded-resource glob in <c>Mbproxy.csproj</c>.
/// A broken or narrowed glob would silently drop a UI asset from the single-file binary;
/// the admin endpoint would then 404 it at runtime with no compile-time failure. This
/// test fails the build instead by comparing the on-disk source folder against the
/// assembly's manifest resources.
/// </summary>
[Trait("Category", "Unit")]
public sealed class EmbeddedAssetsTests
{
    private const string ResourcePrefix = "Mbproxy.Admin.wwwroot.";

    [Fact]
    public void EveryWwwrootFile_IsEmbeddedAsAManifestResource()
    {
        var sourceDir = LocateWwwrootSource();
        var sourceFiles = Directory.GetFiles(sourceDir)
            .Select(Path.GetFileName)
            .Where(n => n is not null)
            .Select(n => n!)
            .ToArray();

        sourceFiles.ShouldNotBeEmpty("the source wwwroot folder should contain UI assets");

        var embedded = typeof(StatusHub).Assembly
            .GetManifestResourceNames()
            .Where(n => n.StartsWith(ResourcePrefix, StringComparison.Ordinal))
            .ToHashSet(StringComparer.Ordinal);

        foreach (var file in sourceFiles)
        {
            embedded.ShouldContain(ResourcePrefix + file,
                $"wwwroot asset '{file}' is not embedded — check the EmbeddedResource glob in Mbproxy.csproj");
        }
    }

    /// <summary>
    /// Walks up from the test assembly directory to the repo and returns
    /// <c>src/Mbproxy/Admin/wwwroot</c> — same upward-search pattern the simulator
    /// fixture uses to find <c>tests/sim</c>.
    /// </summary>
    private static string LocateWwwrootSource()
    {
        var dir = new DirectoryInfo(
            Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ".");
        while (dir is not null)
        {
            var candidate = Path.Combine(dir.FullName, "src", "Mbproxy", "Admin", "wwwroot");
            if (Directory.Exists(candidate))
                return candidate;
            dir = dir.Parent;
        }
        throw new DirectoryNotFoundException(
            "Could not locate src/Mbproxy/Admin/wwwroot above the test assembly.");
    }
}
