package auth

import (
	"crypto/rand"
	"testing"
)

func TestSealOpenAES_Roundtrip(t *testing.T) {
	var key [32]byte
	if _, err := rand.Read(key[:]); err != nil {
		t.Fatal(err)
	}
	const secret = "JBSWY3DPEHPK3PXP" // sample base32 TOTP secret

	blob, err := sealAES(key[:], secret)
	if err != nil {
		t.Fatalf("sealAES: %v", err)
	}
	if string(blob) == secret {
		t.Fatal("ciphertext equals plaintext — not encrypted")
	}

	got, err := openAES(key[:], blob)
	if err != nil {
		t.Fatalf("openAES: %v", err)
	}
	if got != secret {
		t.Fatalf("roundtrip mismatch: got %q want %q", got, secret)
	}
}

func TestOpenAES_TamperAndWrongKey(t *testing.T) {
	var key, other [32]byte
	_, _ = rand.Read(key[:])
	_, _ = rand.Read(other[:])

	blob, err := sealAES(key[:], "secret-value")
	if err != nil {
		t.Fatal(err)
	}

	// Wrong key must fail (GCM auth).
	if _, err := openAES(other[:], blob); err == nil {
		t.Error("openAES with wrong key should fail")
	}

	// Tampered ciphertext must fail.
	bad := append([]byte(nil), blob...)
	bad[len(bad)-1] ^= 0xff
	if _, err := openAES(key[:], bad); err == nil {
		t.Error("openAES with tampered ciphertext should fail")
	}

	// Too-short blob must fail, not panic.
	if _, err := openAES(key[:], []byte{1, 2, 3}); err == nil {
		t.Error("openAES with short blob should fail")
	}
}

func TestNewToken16_UniqueHex(t *testing.T) {
	seen := make(map[string]bool, 100)
	for i := 0; i < 100; i++ {
		tok, err := newToken16()
		if err != nil {
			t.Fatal(err)
		}
		if len(tok) != 32 {
			t.Fatalf("token length = %d, want 32 hex chars", len(tok))
		}
		if seen[tok] {
			t.Fatalf("duplicate token: %s", tok)
		}
		seen[tok] = true
	}
}
