using System.IO;
using ClaudeDo.Releases;

namespace ClaudeDo.Releases.Tests;

public sealed class ChecksumVerifierTests : IDisposable
{
    private readonly string _tempDir;

    public ChecksumVerifierTests()
    {
        _tempDir = Path.Combine(Path.GetTempPath(), "ClaudeDoChecksum-" + Guid.NewGuid().ToString("N"));
        Directory.CreateDirectory(_tempDir);
    }

    public void Dispose()
    {
        try { Directory.Delete(_tempDir, recursive: true); } catch { }
    }

    [Fact]
    public void ComputeSha256_KnownVector_EmptyFile()
    {
        var path = Path.Combine(_tempDir, "empty.bin");
        File.WriteAllBytes(path, Array.Empty<byte>());

        var hash = ChecksumVerifier.ComputeSha256(path);

        Assert.Equal("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", hash);
    }

    [Fact]
    public void ComputeSha256_KnownVector_Hello()
    {
        var path = Path.Combine(_tempDir, "hello.bin");
        File.WriteAllText(path, "hello");

        var hash = ChecksumVerifier.ComputeSha256(path);

        Assert.Equal("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash);
    }

    [Fact]
    public void Verify_ReturnsTrue_WhenHashMatches()
    {
        var path = Path.Combine(_tempDir, "x.bin");
        File.WriteAllText(path, "hello");

        Assert.True(ChecksumVerifier.Verify(path,
            "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"));
    }

    [Fact]
    public void Verify_IsCaseInsensitive()
    {
        var path = Path.Combine(_tempDir, "x.bin");
        File.WriteAllText(path, "hello");

        Assert.True(ChecksumVerifier.Verify(path,
            "2CF24DBA5FB0A30E26E83B2AC5B9E29E1B161E5C1FA7425E73043362938B9824"));
    }

    [Fact]
    public void Verify_ReturnsFalse_OnMismatch()
    {
        var path = Path.Combine(_tempDir, "x.bin");
        File.WriteAllText(path, "hello");

        Assert.False(ChecksumVerifier.Verify(path, new string('0', 64)));
    }

    [Fact]
    public void ParseChecksumsFile_ReadsTwoLines()
    {
        var content = """
            e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  ClaudeDo-0.2.0-win-x64.zip
            2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824  ClaudeDo.Installer-0.2.0.exe
            """;

        var map = ChecksumVerifier.ParseChecksumsFile(content);

        Assert.Equal(2, map.Count);
        Assert.Equal(
            "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
            map["ClaudeDo-0.2.0-win-x64.zip"]);
        Assert.Equal(
            "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
            map["ClaudeDo.Installer-0.2.0.exe"]);
    }

    [Fact]
    public void ParseChecksumsFile_SkipsBlankAndMalformedLines()
    {
        var content = """

            not a line
            e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  file.zip

            """;

        var map = ChecksumVerifier.ParseChecksumsFile(content);

        Assert.Single(map);
        Assert.True(map.ContainsKey("file.zip"));
    }
}
