using FluentAssertions;
using Microsoft.Extensions.Logging;
using DragonISO.Engine.Logging;

namespace DragonISO.Engine.Tests.Logging;

public class EngineLoggingTests : IDisposable
{
    private readonly string _dir;

    public EngineLoggingTests()
    {
        _dir = Path.Combine(Path.GetTempPath(), $"Dragon-ISO-log-{Guid.NewGuid():N}");
    }

    public void Dispose()
    {
        try { Directory.Delete(_dir, recursive: true); } catch { /* best-effort */ }
    }

    [Fact]
    public void CreateDefault_AllLoggers_WriteToFile()
    {
        // Multiple ILoggers from the same factory must all land in the file sink â€”
        // catches regressions in CreateDefault wiring (e.g. if SerilogLoggerFactory
        // swaps to Log.Logger silently and our static singleton isn't set).
        var factory = EngineLogging.CreateDefault(LogLevel.Information, logDirectoryOverride: _dir);
        factory.CreateLogger<EngineLoggingTests>().LogInformation("typed-logger-line");
        factory.CreateLogger("Custom.Category").LogInformation("named-logger-line");
        factory.Dispose(); // disposes the wrapped Serilog logger -> flush + close file

        var logFiles = Directory.GetFiles(_dir, "*.log");
        logFiles.Should().HaveCount(1);

        var content = File.ReadAllText(logFiles[0]);
        content.Should().Contain("typed-logger-line",
            because: "logs from a typed CreateLogger<T> must reach the file sink");
        content.Should().Contain("named-logger-line",
            because: "logs from a named CreateLogger(string) must reach the file sink");
    }

    [Fact]
    public void CreateDefault_LogsAtBelowMinimumLevel_AreSuppressed()
    {
        var factory = EngineLogging.CreateDefault(LogLevel.Warning, logDirectoryOverride: _dir);
        factory.CreateLogger("X").LogInformation("info-should-be-suppressed");
        factory.CreateLogger("X").LogWarning("warn-should-appear");
        factory.Dispose();

        var content = File.ReadAllText(Directory.GetFiles(_dir, "*.log").Single());
        content.Should().NotContain("info-should-be-suppressed");
        content.Should().Contain("warn-should-appear");
    }
}
