package secrets

import (
	"encoding/base64"
	"testing"

	"github.com/stretchr/testify/require"
)

const (
	// This immutable fixture uses the pre-move MeshX storage contract with
	// nonce bytes 0x00 through 0x0b and locks compatibility with persisted rows.
	legacyAESGCMKey        = "0123456789abcdef0123456789abcdef"
	legacyAESGCMPlaintext  = "legacy-meshx-secret"
	legacyAESGCMCiphertext = "AAECAwQFBgcICQoLQYDcHbph/8HNrxnGXLy0Z5Rtd3mqCg/tA2QZ11ZNGwGSDkA"
)

func TestAESGCMCodecOpensLegacyMeshXCiphertext(t *testing.T) {
	t.Parallel()

	codec, err := NewAESGCMCodec([]byte(legacyAESGCMKey))
	require.NoError(t, err)

	plaintext, err := codec.Open(legacyAESGCMCiphertext)
	require.NoError(t, err)
	require.Equal(t, legacyAESGCMPlaintext, plaintext)
}

func TestAESGCMCodecRoundTripsRawNonceCiphertext(t *testing.T) {
	t.Parallel()

	codec, err := NewAESGCMCodec([]byte(legacyAESGCMKey))
	require.NoError(t, err)

	encoded, err := codec.Seal("new-secret")
	require.NoError(t, err)
	require.NotContains(t, encoded, "=")

	sealed, err := base64.RawStdEncoding.DecodeString(encoded)
	require.NoError(t, err)
	require.Len(t, sealed, codec.aead.NonceSize()+len("new-secret")+codec.aead.Overhead())

	plaintext, err := codec.Open(encoded)
	require.NoError(t, err)
	require.Equal(t, "new-secret", plaintext)
}

func TestAESGCMCodecRejectsInvalidInputs(t *testing.T) {
	t.Parallel()

	_, err := NewAESGCMCodec([]byte("short"))
	require.EqualError(t, err, "AES-GCM key must be 32 bytes")

	codec, err := NewAESGCMCodec([]byte(legacyAESGCMKey))
	require.NoError(t, err)

	_, err = codec.Open("not base64")
	require.ErrorContains(t, err, "decode AES-GCM value")
	_, err = codec.Open(base64.RawStdEncoding.EncodeToString(make([]byte, codec.aead.NonceSize())))
	require.EqualError(t, err, "AES-GCM value is invalid")
	tampered := []byte(legacyAESGCMCiphertext)
	tampered[len(tampered)/2] = 'A'
	_, err = codec.Open(string(tampered))
	require.ErrorContains(t, err, "open AES-GCM value")
}
