using OF_DL.Enumerations;
using OF_DL.Models.Config;
using OF_DL.Services;

namespace OF_DL.Tests.Services;

[Collection("NonParallel")]
public class ConfigServiceTests
{
    [Fact]
    public async Task LoadConfigurationAsync_CreatesDefaultConfigWhenMissing()
    {
        using TempFolder temp = new();
        using CurrentDirectoryScope _ = new(temp.Path);
        FakeLoggingService loggingService = new();
        ConfigService service = new(loggingService);

        bool result = await service.LoadConfigurationAsync([]);

        Assert.True(result);
        Assert.True(File.Exists("config.conf"));
        Assert.True(loggingService.UpdateCount > 0);
        Assert.Equal(service.CurrentConfig.LoggingLevel, loggingService.LastLevel);
    }

    [Fact]
    public async Task LoadConfigurationAsync_OverridesNonInteractiveFromCli()
    {
        using TempFolder temp = new();
        using CurrentDirectoryScope _ = new(temp.Path);
        FakeLoggingService loggingService = new();
        ConfigService service = new(loggingService);
        await service.SaveConfigurationAsync();

        bool result = await service.LoadConfigurationAsync(["--non-interactive"]);

        Assert.True(result);
        Assert.True(service.IsCliNonInteractive);
        Assert.True(service.CurrentConfig.NonInteractiveMode);
    }

    [Fact]
    public async Task LoadConfigurationAsync_ReturnsFalseWhenInvalidFilenameFormat()
    {
        using TempFolder temp = new();
        using CurrentDirectoryScope _ = new(temp.Path);
        FakeLoggingService loggingService = new();
        ConfigService service = new(loggingService);
        await service.SaveConfigurationAsync();

        string hocon = await File.ReadAllTextAsync("config.conf");
        hocon = hocon.Replace("PaidPostFileNameFormat = \"\"",
            "PaidPostFileNameFormat = \"invalid-format\"");
        await File.WriteAllTextAsync("config.conf", hocon);

        bool result = await service.LoadConfigurationAsync([]);

        Assert.False(result);
    }

    [Fact]
    public void ApplyToggleableSelections_UpdatesConfigAndReturnsChange()
    {
        FakeLoggingService loggingService = new();
        ConfigService service = new(loggingService);
        Config initialConfig = new()
        {
            DownloadPosts = true,
            DownloadMessages = true,
            DownloadPath = "/downloads",
            LoggingLevel = LoggingLevel.Warning
        };
        service.UpdateConfig(initialConfig);

        bool changed = service.ApplyToggleableSelections(["DownloadPosts"]);

        Assert.True(changed);
        Assert.True(service.CurrentConfig.DownloadPosts);
        Assert.False(service.CurrentConfig.DownloadMessages);
        Assert.Equal("/downloads", service.CurrentConfig.DownloadPath);
        Assert.Equal(LoggingLevel.Warning, loggingService.LastLevel);
    }

}
