using System.Security.Cryptography;
using System.Text;
using Metin2Launcher.Transfer;
using Xunit;

namespace Metin2Launcher.Tests;

public class FileHasherTests
{
    [Fact]
    public void HashBytes_matches_known_good_value_for_empty_input()
    {
        // Known sha256 of the empty string.
        const string empty = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
        Assert.Equal(empty, FileHasher.HashBytes(ReadOnlySpan<byte>.Empty));
    }

    [Fact]
    public void HashBytes_matches_known_good_value_for_abc()
    {
        // Standard NIST test vector: sha256("abc")
        const string expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
        Assert.Equal(expected, FileHasher.HashBytes(Encoding.ASCII.GetBytes("abc")));
    }

    [Fact]
    public void HashFileOrNull_returns_null_for_missing_file()
    {
        var path = Path.Combine(Path.GetTempPath(), "metin-test-missing-" + Guid.NewGuid());
        Assert.Null(FileHasher.HashFileOrNull(path));
    }

    [Fact]
    public void HashStream_matches_SHA256_on_random_10MB_input()
    {
        var rand = new Random(12345);
        var buf = new byte[10 * 1024 * 1024];
        rand.NextBytes(buf);

        var expected = Convert.ToHexString(SHA256.HashData(buf)).ToLowerInvariant();
        var tmp = Path.GetTempFileName();
        try
        {
            File.WriteAllBytes(tmp, buf);
            Assert.Equal(expected, FileHasher.HashFileOrNull(tmp));

            using var ms = new MemoryStream(buf);
            Assert.Equal(expected, FileHasher.HashStream(ms));
        }
        finally
        {
            File.Delete(tmp);
        }
    }
}
