package updater

import (
	"crypto/ed25519"
	"crypto/rand"
	"encoding/base64"
	"testing"
)

func TestVerifySignature_valid(t *testing.T) {
	pub, priv, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	data := []byte("release binary content")
	sig := ed25519.Sign(priv, data)

	trustedKeysRaw = base64.StdEncoding.EncodeToString(pub)
	t.Cleanup(func() { trustedKeysRaw = "" })

	if err := VerifySignature(data, sig); err != nil {
		t.Fatalf("expected valid signature to pass: %v", err)
	}
}

func TestVerifySignature_tampered(t *testing.T) {
	pub, priv, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}
	_ = pub

	data := []byte("original content")
	sig := ed25519.Sign(priv, data)

	// different key embedded
	pub2, _, _ := ed25519.GenerateKey(rand.Reader)
	trustedKeysRaw = base64.StdEncoding.EncodeToString(pub2)
	t.Cleanup(func() { trustedKeysRaw = "" })

	if err := VerifySignature(data, sig); err == nil {
		t.Fatal("expected tampered signature to fail")
	}
}

func TestVerifySignature_multiKey_anyMatches(t *testing.T) {
	pub1, _, _ := ed25519.GenerateKey(rand.Reader)
	pub2, priv2, _ := ed25519.GenerateKey(rand.Reader)

	data := []byte("signed by developer 2")
	sig := ed25519.Sign(priv2, data)

	trustedKeysRaw = base64.StdEncoding.EncodeToString(pub1) + ":" +
		base64.StdEncoding.EncodeToString(pub2)
	t.Cleanup(func() { trustedKeysRaw = "" })

	if err := VerifySignature(data, sig); err != nil {
		t.Fatalf("expected any-key match to pass: %v", err)
	}
}

func TestVerifySignature_devBuild(t *testing.T) {
	trustedKeysRaw = ""
	_, priv, _ := ed25519.GenerateKey(rand.Reader)
	data := []byte("content")
	sig := ed25519.Sign(priv, data)

	if err := VerifySignature(data, sig); err == nil {
		t.Fatal("expected dev build (no keys) to fail")
	}
}
