using System.Text;
using Metin2Launcher.Formats;
using Metin2Launcher.Manifest;
using Xunit;
using ManifestDto = Metin2Launcher.Manifest.Manifest;

namespace Metin2Launcher.Tests;

public class ReleaseFormatFactoryTests
{
    [Fact]
    public void Resolves_legacy_by_default()
    {
        var f = ReleaseFormatFactory.Resolve("legacy-json-blob");
        Assert.IsType<LegacyJsonBlobFormat>(f);
    }

    [Fact]
    public void Resolves_m2pack()
    {
        var f = ReleaseFormatFactory.Resolve("m2pack");
        Assert.IsType<M2PackFormat>(f);
    }

    [Fact]
    public void Throws_on_unknown_format()
    {
        Assert.Throws<NotSupportedException>(() =>
            ReleaseFormatFactory.Resolve("evil-format"));
    }

    [Fact]
    public void Manifest_without_format_defaults_to_legacy()
    {
        var m = new ManifestDto { Version = "v1" };
        Assert.Equal("legacy-json-blob", m.EffectiveFormat);
    }

    [Fact]
    public void Manifest_with_blank_format_defaults_to_legacy()
    {
        var m = new ManifestDto { Version = "v1", Format = "   " };
        Assert.Equal("legacy-json-blob", m.EffectiveFormat);
    }

    [Fact]
    public void Manifest_with_explicit_format_is_honoured()
    {
        var m = new ManifestDto { Version = "v1", Format = "m2pack" };
        Assert.Equal("m2pack", m.EffectiveFormat);
    }

    [Fact]
    public void Loader_tolerates_unknown_top_level_field_next_to_format()
    {
        const string json = """
{
  "format": "m2pack",
  "version": "2026.04.14-1",
  "created_at": "2026-04-14T14:00:00Z",
  "future_field": {"nested": 1},
  "launcher": {"path": "Metin2Launcher.exe", "sha256": "abcd", "size": 1},
  "files": []
}
""";
        var m = ManifestLoader.Parse(Encoding.UTF8.GetBytes(json));
        Assert.Equal("m2pack", m.EffectiveFormat);
        Assert.Equal("2026.04.14-1", m.Version);
    }

    [Fact]
    public void Loader_parses_manifest_without_format_as_legacy()
    {
        const string json = """
{
  "version": "2026.04.14-1",
  "created_at": "2026-04-14T14:00:00Z",
  "launcher": {"path": "Metin2Launcher.exe", "sha256": "abcd", "size": 1},
  "files": []
}
""";
        var m = ManifestLoader.Parse(Encoding.UTF8.GetBytes(json));
        Assert.Null(m.Format);
        Assert.Equal("legacy-json-blob", m.EffectiveFormat);
    }
}
