package namedcredential

import (
	"bytes"
	"encoding/base64"
	"errors"
	"strings"
	"testing"
)

func TestSecretCipher_RoundTrip(t *testing.T) {
	key := bytes.Repeat([]byte{0x42}, 32) // deterministic test key
	c, err := NewSecretCipherFromKey(key)
	if err != nil {
		t.Fatal(err)
	}

	cases := []string{"", "x", "short", "日本語abcd", strings.Repeat("a", 4096)}
	for _, pt := range cases {
		ct, err := c.Encrypt(pt)
		if err != nil {
			t.Fatalf("encrypt %q: %v", pt, err)
		}
		got, err := c.Decrypt(ct)
		if err != nil {
			t.Fatalf("decrypt: %v", err)
		}
		if got != pt {
			t.Errorf("roundtrip: got %q, want %q", got, pt)
		}
	}
}

func TestSecretCipher_RejectsTamperedCiphertext(t *testing.T) {
	key := bytes.Repeat([]byte{0x42}, 32)
	c, _ := NewSecretCipherFromKey(key)
	ct, _ := c.Encrypt("the-real-secret")

	// flip a byte in the middle of the base64-decoded envelope
	raw, _ := base64.StdEncoding.DecodeString(ct)
	raw[len(raw)/2] ^= 0xFF
	tampered := base64.StdEncoding.EncodeToString(raw)

	_, err := c.Decrypt(tampered)
	if !errors.Is(err, ErrCiphertextCorrupt) {
		t.Errorf("expected ErrCiphertextCorrupt, got %v", err)
	}
}

func TestSecretCipher_RejectsWrongKey(t *testing.T) {
	c1, _ := NewSecretCipherFromKey(bytes.Repeat([]byte{0x42}, 32))
	c2, _ := NewSecretCipherFromKey(bytes.Repeat([]byte{0x99}, 32))
	ct, _ := c1.Encrypt("the-real-secret")

	_, err := c2.Decrypt(ct)
	if !errors.Is(err, ErrCiphertextCorrupt) {
		t.Errorf("expected ErrCiphertextCorrupt with wrong key, got %v", err)
	}
}

func TestSecretCipher_UnknownVersionRejected(t *testing.T) {
	c, _ := NewSecretCipherFromKey(bytes.Repeat([]byte{0x42}, 32))
	ct, _ := c.Encrypt("x")
	raw, _ := base64.StdEncoding.DecodeString(ct)
	raw[0] = 0xFE // unknown version
	bad := base64.StdEncoding.EncodeToString(raw)
	_, err := c.Decrypt(bad)
	if !errors.Is(err, ErrCiphertextCorrupt) {
		t.Errorf("expected ErrCiphertextCorrupt for unknown version, got %v", err)
	}
}

func TestNewSecretCipher_MissingEnvVar(t *testing.T) {
	t.Setenv(MasterKeyEnvVar, "")
	_, err := NewSecretCipher()
	if !errors.Is(err, ErrMasterKeyMissing) {
		t.Errorf("expected ErrMasterKeyMissing, got %v", err)
	}
}

func TestNewSecretCipher_ValidEnvVar(t *testing.T) {
	key := bytes.Repeat([]byte{0x55}, 32)
	t.Setenv(MasterKeyEnvVar, base64.StdEncoding.EncodeToString(key))
	c, err := NewSecretCipher()
	if err != nil {
		t.Fatalf("constructor: %v", err)
	}
	ct, _ := c.Encrypt("hello")
	got, _ := c.Decrypt(ct)
	if got != "hello" {
		t.Errorf("roundtrip via env: got %q", got)
	}
}
