using NSec.Cryptography;

namespace Metin2Launcher.Manifest;

/// <summary>
/// Ed25519 detached-signature verification via NSec.Cryptography (libsodium).
///
/// .NET 8's BCL does not implement Ed25519, so we rely on NSec. The public key
/// is a 32-byte raw Ed25519 key supplied as hex (see LauncherConfig.PublicKeyHex).
/// </summary>
public static class SignatureVerifier
{
    /// <summary>Verifies <paramref name="signature"/> over <paramref name="message"/> with a hex-encoded public key.</summary>
    public static bool Verify(ReadOnlySpan<byte> message, ReadOnlySpan<byte> signature, string publicKeyHex)
    {
        if (string.IsNullOrEmpty(publicKeyHex))
            return false;

        byte[] pubBytes;
        try
        {
            pubBytes = Convert.FromHexString(publicKeyHex);
        }
        catch (FormatException)
        {
            return false;
        }

        return Verify(message, signature, pubBytes);
    }

    public static bool Verify(ReadOnlySpan<byte> message, ReadOnlySpan<byte> signature, ReadOnlySpan<byte> publicKey)
    {
        if (publicKey.Length != 32)
            return false;
        if (signature.Length != 64)
            return false;

        var algo = SignatureAlgorithm.Ed25519;
        PublicKey key;
        try
        {
            key = PublicKey.Import(algo, publicKey, KeyBlobFormat.RawPublicKey);
        }
        catch
        {
            return false;
        }
        return algo.Verify(key, message, signature);
    }
}
