package oauth

import (
	"crypto/sha256"
	"encoding/base64"
	"strings"
	"testing"
)

// Helper function to create a test config
func testConfig() *Config {
	return &Config{
		PrivateKey: "test_private_key_for_testing_12345",
	}
}

// TestGenerateState_Success tests the happy path of state generation
func TestGenerateState_Success(t *testing.T) {
	cfg := testConfig()
	data := "test_data_payload"

	state, userAgentKey, err := GenerateState(cfg, data)

	if err != nil {
		t.Fatalf("Expected no error, got: %v", err)
	}

	if state == "" {
		t.Error("Expected non-empty state")
	}

	if len(userAgentKey) != 32 {
		t.Errorf("Expected userAgentKey to be 32 bytes, got %d", len(userAgentKey))
	}

	// Verify state format: data.random.signature
	parts := strings.Split(state, ".")
	if len(parts) != 3 {
		t.Errorf("Expected state to have 3 parts, got %d", len(parts))
	}

	// Verify data is preserved
	if parts[0] != data {
		t.Errorf("Expected data to be '%s', got '%s'", data, parts[0])
	}

	// Verify random part is base64 encoded
	randomBytes, err := base64.RawURLEncoding.DecodeString(parts[1])
	if err != nil {
		t.Errorf("Expected random part to be valid base64: %v", err)
	}
	if len(randomBytes) != 32 {
		t.Errorf("Expected random to be 32 bytes when decoded, got %d", len(randomBytes))
	}

	// Verify signature part is base64 encoded
	sigBytes, err := base64.RawURLEncoding.DecodeString(parts[2])
	if err != nil {
		t.Errorf("Expected signature part to be valid base64: %v", err)
	}
	if len(sigBytes) != 32 {
		t.Errorf("Expected signature to be 32 bytes (SHA256), got %d", len(sigBytes))
	}
}

// TestGenerateState_NilConfig tests that nil config returns error
func TestGenerateState_NilConfig(t *testing.T) {
	_, _, err := GenerateState(nil, "test_data")

	if err == nil {
		t.Fatal("Expected error for nil config, got nil")
	}

	if !strings.Contains(err.Error(), "cfg cannot be nil") {
		t.Errorf("Expected error message about nil config, got: %v", err)
	}
}

// TestGenerateState_EmptyPrivateKey tests that empty private key returns error
func TestGenerateState_EmptyPrivateKey(t *testing.T) {
	cfg := &Config{PrivateKey: ""}
	_, _, err := GenerateState(cfg, "test_data")

	if err == nil {
		t.Fatal("Expected error for empty private key, got nil")
	}

	if !strings.Contains(err.Error(), "private key cannot be empty") {
		t.Errorf("Expected error message about empty private key, got: %v", err)
	}
}

// TestGenerateState_EmptyData tests that empty data returns error
func TestGenerateState_EmptyData(t *testing.T) {
	cfg := testConfig()
	_, _, err := GenerateState(cfg, "")

	if err == nil {
		t.Fatal("Expected error for empty data, got nil")
	}

	if !strings.Contains(err.Error(), "data cannot be empty") {
		t.Errorf("Expected error message about empty data, got: %v", err)
	}
}

// TestGenerateState_Randomness tests that multiple calls generate different states
func TestGenerateState_Randomness(t *testing.T) {
	cfg := testConfig()
	data := "same_data"

	state1, _, err1 := GenerateState(cfg, data)
	state2, _, err2 := GenerateState(cfg, data)

	if err1 != nil || err2 != nil {
		t.Fatalf("Unexpected errors: %v, %v", err1, err2)
	}

	if state1 == state2 {
		t.Error("Expected different states for multiple calls, got identical states")
	}
}

// TestGenerateState_DifferentData tests states with different data payloads
func TestGenerateState_DifferentData(t *testing.T) {
	cfg := testConfig()

	testCases := []string{
		"simple",
		"with-dashes",
		"with_underscores",
		"123456789",
		"MixedCase123",
	}

	for _, data := range testCases {
		t.Run(data, func(t *testing.T) {
			state, userAgentKey, err := GenerateState(cfg, data)

			if err != nil {
				t.Fatalf("Unexpected error for data '%s': %v", data, err)
			}

			if !strings.HasPrefix(state, data+".") {
				t.Errorf("Expected state to start with '%s.', got: %s", data, state)
			}

			if len(userAgentKey) != 32 {
				t.Errorf("Expected userAgentKey to be 32 bytes, got %d", len(userAgentKey))
			}
		})
	}
}

// TestVerifyState_Success tests the happy path of state verification
func TestVerifyState_Success(t *testing.T) {
	cfg := testConfig()
	data := "test_data"

	// Generate state
	state, userAgentKey, err := GenerateState(cfg, data)
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Verify state
	extractedData, err := VerifyState(cfg, state, userAgentKey)

	if err != nil {
		t.Fatalf("Expected no error, got: %v", err)
	}

	if extractedData != data {
		t.Errorf("Expected extracted data to be '%s', got '%s'", data, extractedData)
	}
}

// TestVerifyState_NilConfig tests that nil config returns error
func TestVerifyState_NilConfig(t *testing.T) {
	_, err := VerifyState(nil, "state", []byte("key"))

	if err == nil {
		t.Fatal("Expected error for nil config, got nil")
	}

	if !strings.Contains(err.Error(), "cfg cannot be nil") {
		t.Errorf("Expected error message about nil config, got: %v", err)
	}
}

// TestVerifyState_EmptyPrivateKey tests that empty private key returns error
func TestVerifyState_EmptyPrivateKey(t *testing.T) {
	cfg := &Config{PrivateKey: ""}
	_, err := VerifyState(cfg, "state", []byte("key"))

	if err == nil {
		t.Fatal("Expected error for empty private key, got nil")
	}

	if !strings.Contains(err.Error(), "private key cannot be empty") {
		t.Errorf("Expected error message about empty private key, got: %v", err)
	}
}

// TestVerifyState_EmptyState tests that empty state returns error
func TestVerifyState_EmptyState(t *testing.T) {
	cfg := testConfig()
	_, err := VerifyState(cfg, "", []byte("key"))

	if err == nil {
		t.Fatal("Expected error for empty state, got nil")
	}

	if !strings.Contains(err.Error(), "state cannot be empty") {
		t.Errorf("Expected error message about empty state, got: %v", err)
	}
}

// TestVerifyState_EmptyUserAgentKey tests that empty userAgentKey returns error
func TestVerifyState_EmptyUserAgentKey(t *testing.T) {
	cfg := testConfig()
	_, err := VerifyState(cfg, "data.random.signature", []byte{})

	if err == nil {
		t.Fatal("Expected error for empty userAgentKey, got nil")
	}

	if !strings.Contains(err.Error(), "userAgentKey cannot be empty") {
		t.Errorf("Expected error message about empty userAgentKey, got: %v", err)
	}
}

// TestVerifyState_WrongUserAgentKey tests MITM protection
func TestVerifyState_WrongUserAgentKey(t *testing.T) {
	cfg := testConfig()

	// Generate first state
	state, _, err := GenerateState(cfg, "test_data")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Generate a different userAgentKey
	_, wrongKey, err := GenerateState(cfg, "other_data")
	if err != nil {
		t.Fatalf("Failed to generate second state: %v", err)
	}

	// Try to verify with wrong key
	_, err = VerifyState(cfg, state, wrongKey)

	if err == nil {
		t.Error("Expected error for invalid signature")
	}

	if !strings.Contains(err.Error(), "invalid state signature") {
		t.Errorf("Expected error about invalid signature, got: %v", err)
	}
}

// TestVerifyState_TamperedData tests tampering detection
func TestVerifyState_TamperedData(t *testing.T) {
	cfg := testConfig()

	// Generate state
	state, userAgentKey, err := GenerateState(cfg, "original_data")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Tamper with the data portion
	parts := strings.Split(state, ".")
	parts[0] = "tampered_data"
	tamperedState := strings.Join(parts, ".")

	// Try to verify tampered state
	_, err = VerifyState(cfg, tamperedState, userAgentKey)

	if err == nil {
		t.Error("Expected error for tampered state")
	}
}

// TestVerifyState_TamperedRandom tests tampering with random portion
func TestVerifyState_TamperedRandom(t *testing.T) {
	cfg := testConfig()

	// Generate state
	state, userAgentKey, err := GenerateState(cfg, "test_data")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Tamper with the random portion
	parts := strings.Split(state, ".")
	parts[1] = base64.RawURLEncoding.EncodeToString([]byte("tampered_random_value_here12"))
	tamperedState := strings.Join(parts, ".")

	// Try to verify tampered state
	_, err = VerifyState(cfg, tamperedState, userAgentKey)

	if err == nil {
		t.Error("Expected error for tampered state")
	}
}

// TestVerifyState_TamperedSignature tests tampering with signature
func TestVerifyState_TamperedSignature(t *testing.T) {
	cfg := testConfig()

	// Generate state
	state, userAgentKey, err := GenerateState(cfg, "test_data")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Tamper with the signature portion
	parts := strings.Split(state, ".")
	// Create a different valid base64 string
	parts[2] = base64.RawURLEncoding.EncodeToString(sha256.New().Sum([]byte("tampered")))
	tamperedState := strings.Join(parts, ".")

	// Try to verify tampered state
	_, err = VerifyState(cfg, tamperedState, userAgentKey)

	if err == nil {
		t.Error("Expected error for tampered signature")
	}
}

// TestVerifyState_MalformedState_TwoParts tests state with only 2 parts
func TestVerifyState_MalformedState_TwoParts(t *testing.T) {
	cfg := testConfig()
	malformedState := "data.random"

	_, err := VerifyState(cfg, malformedState, []byte("key123456789012345678901234567890"))

	if err == nil {
		t.Fatal("Expected error for malformed state")
	}

	if !strings.Contains(err.Error(), "must have exactly 3 parts") {
		t.Errorf("Expected error about incorrect number of parts, got: %v", err)
	}
}

// TestVerifyState_MalformedState_FourParts tests state with 4 parts
func TestVerifyState_MalformedState_FourParts(t *testing.T) {
	cfg := testConfig()
	malformedState := "data.random.signature.extra"

	_, err := VerifyState(cfg, malformedState, []byte("key123456789012345678901234567890"))

	if err == nil {
		t.Fatal("Expected error for malformed state")
	}

	if !strings.Contains(err.Error(), "must have exactly 3 parts") {
		t.Errorf("Expected error about incorrect number of parts, got: %v", err)
	}
}

// TestVerifyState_EmptyStateParts tests state with empty parts
func TestVerifyState_EmptyStateParts(t *testing.T) {
	cfg := testConfig()
	testCases := []struct {
		name  string
		state string
	}{
		{"empty data", ".random.signature"},
		{"empty random", "data..signature"},
		{"empty signature", "data.random."},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			_, err := VerifyState(cfg, tc.state, []byte("key123456789012345678901234567890"))

			if err == nil {
				t.Fatal("Expected error for state with empty parts")
			}

			if !strings.Contains(err.Error(), "state parts cannot be empty") {
				t.Errorf("Expected error about empty parts, got: %v", err)
			}
		})
	}
}

// TestVerifyState_InvalidBase64Signature tests state with invalid base64 in signature
func TestVerifyState_InvalidBase64Signature(t *testing.T) {
	cfg := testConfig()
	invalidState := "data.random.invalid@base64!"

	_, err := VerifyState(cfg, invalidState, []byte("key123456789012345678901234567890"))

	if err == nil {
		t.Fatal("Expected error for invalid base64 signature")
	}

	if !strings.Contains(err.Error(), "failed to decode") {
		t.Errorf("Expected error about decoding signature, got: %v", err)
	}
}

// TestVerifyState_DifferentPrivateKey tests that different private keys fail verification
func TestVerifyState_DifferentPrivateKey(t *testing.T) {
	cfg1 := &Config{PrivateKey: "private_key_1"}
	cfg2 := &Config{PrivateKey: "private_key_2"}

	// Generate with first config
	state, userAgentKey, err := GenerateState(cfg1, "test_data")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Try to verify with second config
	_, err = VerifyState(cfg2, state, userAgentKey)

	if err == nil {
		t.Error("Expected error for mismatched private key")
	}
}

// TestRoundTrip tests complete round trip with various data payloads
func TestRoundTrip(t *testing.T) {
	cfg := testConfig()

	testCases := []string{
		"simple",
		"with-dashes-and-numbers-123",
		"MixedCaseData",
		"user_token_abc123",
		"link_resource_xyz789",
	}

	for _, data := range testCases {
		t.Run(data, func(t *testing.T) {
			// Generate
			state, userAgentKey, err := GenerateState(cfg, data)
			if err != nil {
				t.Fatalf("Failed to generate state: %v", err)
			}

			// Verify
			extractedData, err := VerifyState(cfg, state, userAgentKey)
			if err != nil {
				t.Fatalf("Failed to verify state: %v", err)
			}

			if extractedData != data {
				t.Errorf("Expected extracted data '%s', got '%s'", data, extractedData)
			}
		})
	}
}

// TestConcurrentGeneration tests that concurrent state generation works correctly
func TestConcurrentGeneration(t *testing.T) {
	cfg := testConfig()
	data := "concurrent_test"

	const numGoroutines = 10
	results := make(chan string, numGoroutines)
	errors := make(chan error, numGoroutines)

	// Generate states concurrently
	for range numGoroutines {
		go func() {
			state, userAgentKey, err := GenerateState(cfg, data)
			if err != nil {
				errors <- err
				return
			}

			// Verify immediately
			_, verifyErr := VerifyState(cfg, state, userAgentKey)
			if verifyErr != nil {
				errors <- verifyErr
				return
			}

			results <- state
		}()
	}

	// Collect results
	states := make(map[string]bool)
	for range numGoroutines {
		select {
		case state := <-results:
			if states[state] {
				t.Errorf("Duplicate state generated: %s", state)
			}
			states[state] = true
		case err := <-errors:
			t.Errorf("Concurrent generation error: %v", err)
		}
	}

	if len(states) != numGoroutines {
		t.Errorf("Expected %d unique states, got %d", numGoroutines, len(states))
	}
}

// TestStateFormatCompatibility ensures state is URL-safe
func TestStateFormatCompatibility(t *testing.T) {
	cfg := testConfig()
	data := "url_safe_test"

	state, _, err := GenerateState(cfg, data)
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Check that state doesn't contain characters that need URL encoding
	unsafeChars := []string{"+", "/", "=", " ", "&", "?", "#"}
	for _, char := range unsafeChars {
		if strings.Contains(state, char) {
			t.Errorf("State contains URL-unsafe character '%s': %s", char, state)
		}
	}
}

// TestMITM_AttackerCannotSubstituteState verifies MITM protection actually works
// An attacker obtains their own valid state but tries to use it with victim's session
func TestMITM_AttackerCannotSubstituteState(t *testing.T) {
	cfg := testConfig()

	// Victim generates a state for their login
	victimState, victimKey, err := GenerateState(cfg, "victim_data")
	if err != nil {
		t.Fatalf("Failed to generate victim state: %v", err)
	}

	// Attacker generates their own valid state (they can request this from the server)
	attackerState, attackerKey, err := GenerateState(cfg, "attacker_data")
	if err != nil {
		t.Fatalf("Failed to generate attacker state: %v", err)
	}

	// Both states should be valid on their own
	_, err = VerifyState(cfg, victimState, victimKey)
	if err != nil {
		t.Fatalf("Victim state should be valid: err=%v", err)
	}

	_, err = VerifyState(cfg, attackerState, attackerKey)
	if err != nil {
		t.Fatalf("Attacker state should be valid: err=%v", err)
	}

	// MITM Attack Scenario 1: Attacker substitutes their state but victim has their cookie
	// This should FAIL because attackerState was signed with attackerKey, not victimKey
	_, err = VerifyState(cfg, attackerState, victimKey)
	if err == nil {
		t.Error("Expected error when attacker substitutes state")
	}

	// MITM Attack Scenario 2: Attacker uses victim's state but has their own cookie
	// This should also FAIL
	_, err = VerifyState(cfg, victimState, attackerKey)
	if err == nil {
		t.Error("Expected error when attacker uses victim's state")
	}

	// The key insight: even though both states are "valid", they are bound to their respective cookies
	// An attacker cannot mix and match states and cookies
	t.Log("✓ MITM protection verified: States are cryptographically bound to their userAgentKey cookies")
}

// TestCSRF_AttackerCannotForgeState verifies CSRF protection
// An attacker tries to forge a state parameter without knowing the private key
func TestCSRF_AttackerCannotForgeState(t *testing.T) {
	cfg := testConfig()

	// Attacker doesn't know the private key, but tries to forge a state
	// They might try to construct: "malicious_data.random.signature"

	// Attempt 1: Use a random signature
	randomSig := base64.RawURLEncoding.EncodeToString([]byte("random_signature_attempt_12345678"))
	forgedState1 := "malicious_data.somefakerandom." + randomSig

	// Generate a real userAgentKey (attacker might try to get this)
	_, realKey, err := GenerateState(cfg, "legitimate_data")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Try to verify forged state
	_, err = VerifyState(cfg, forgedState1, realKey)
	if err == nil {
		t.Error("CSRF VULNERABILITY: Attacker forged a valid state without private key!")
	}

	// Attempt 2: Attacker tries to compute signature without private key
	// They use: SHA256(data + "." + random + userAgentKey) - missing privateKey
	attackerPayload := "malicious_data.fakerandom" + base64.RawURLEncoding.EncodeToString(realKey)
	hash := sha256.Sum256([]byte(attackerPayload))
	attackerSig := base64.RawURLEncoding.EncodeToString(hash[:])
	forgedState2 := "malicious_data.fakerandom." + attackerSig

	_, err = VerifyState(cfg, forgedState2, realKey)
	if err == nil {
		t.Error("CSRF VULNERABILITY: Attacker forged valid state without private key!")
	}

	t.Log("✓ CSRF protection verified: Cannot forge state without private key")
}

// TestTampering_SignatureDetectsAllModifications verifies tamper detection
func TestTampering_SignatureDetectsAllModifications(t *testing.T) {
	cfg := testConfig()

	// Generate a valid state
	originalState, userAgentKey, err := GenerateState(cfg, "original_data")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Verify original is valid
	data, err := VerifyState(cfg, originalState, userAgentKey)
	if err != nil || data != "original_data" {
		t.Fatalf("Original state should be valid")
	}

	parts := strings.Split(originalState, ".")

	// Test 1: Attacker modifies data but keeps signature
	tamperedState := "modified_data." + parts[1] + "." + parts[2]
	_, err = VerifyState(cfg, tamperedState, userAgentKey)
	if err == nil {
		t.Error("TAMPER VULNERABILITY: Modified data not detected!")
	}

	// Test 2: Attacker modifies random but keeps signature
	newRandom := base64.RawURLEncoding.EncodeToString([]byte("new_random_value_32bytes_long!!"))
	tamperedState = parts[0] + "." + newRandom + "." + parts[2]
	_, err = VerifyState(cfg, tamperedState, userAgentKey)
	if err == nil {
		t.Error("TAMPER VULNERABILITY: Modified random not detected!")
	}

	// Test 3: Attacker tries to recompute signature but doesn't have privateKey
	// They compute: SHA256(modified_data + "." + random + userAgentKey)
	attackerPayload := "modified_data." + parts[1] + base64.RawURLEncoding.EncodeToString(userAgentKey)
	hash := sha256.Sum256([]byte(attackerPayload))
	attackerSig := base64.RawURLEncoding.EncodeToString(hash[:])
	tamperedState = "modified_data." + parts[1] + "." + attackerSig
	_, err = VerifyState(cfg, tamperedState, userAgentKey)
	if err == nil {
		t.Error("TAMPER VULNERABILITY: Attacker recomputed signature without private key!")
	}

	// Test 4: Single bit flip in signature
	sigBytes, _ := base64.RawURLEncoding.DecodeString(parts[2])
	sigBytes[0] ^= 0x01 // Flip one bit
	flippedSig := base64.RawURLEncoding.EncodeToString(sigBytes)
	tamperedState = parts[0] + "." + parts[1] + "." + flippedSig
	_, err = VerifyState(cfg, tamperedState, userAgentKey)
	if err == nil {
		t.Error("TAMPER VULNERABILITY: Single bit flip in signature not detected!")
	}

	t.Log("✓ Tamper detection verified: All modifications to state are detected")
}

// TestReplay_DifferentSessionsCannotReuseState verifies replay protection
func TestReplay_DifferentSessionsCannotReuseState(t *testing.T) {
	cfg := testConfig()

	// Session 1: User initiates OAuth flow
	state1, key1, err := GenerateState(cfg, "session1_data")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// State is valid for session 1
	_, err = VerifyState(cfg, state1, key1)
	if err != nil {
		t.Fatalf("State should be valid for session 1")
	}

	// Session 2: Same user (or attacker) initiates a new OAuth flow
	state2, key2, err := GenerateState(cfg, "session1_data") // same data
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Replay Attack: Try to use state1 with key2
	_, err = VerifyState(cfg, state1, key2)
	if err == nil {
		t.Error("REPLAY VULNERABILITY: State from session 1 was accepted in session 2!")
	}

	// Even with same data, each session should have unique state+key binding
	if state1 == state2 {
		t.Error("REPLAY VULNERABILITY: Same data produces identical states!")
	}

	t.Log("✓ Replay protection verified: States are bound to specific session cookies")
}

// TestConstantTimeComparison verifies that signature comparison is timing-safe
// This is a behavioral test - we can't easily test timing, but we can verify the function is used
func TestConstantTimeComparison_IsUsed(t *testing.T) {
	cfg := testConfig()

	// Generate valid state
	state, userAgentKey, err := GenerateState(cfg, "test")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Create states with signatures that differ at different positions
	parts := strings.Split(state, ".")
	originalSig, _ := base64.RawURLEncoding.DecodeString(parts[2])

	testCases := []struct {
		name     string
		position int
	}{
		{"first byte differs", 0},
		{"middle byte differs", 16},
		{"last byte differs", 31},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			// Create signature that differs at specific position
			tamperedSig := make([]byte, len(originalSig))
			copy(tamperedSig, originalSig)
			tamperedSig[tc.position] ^= 0xFF // Flip all bits

			tamperedSigStr := base64.RawURLEncoding.EncodeToString(tamperedSig)
			tamperedState := parts[0] + "." + parts[1] + "." + tamperedSigStr

			// All should fail verification
			_, err := VerifyState(cfg, tamperedState, userAgentKey)
			if err == nil {
				t.Errorf("Tampered signature at position %d should be invalid", tc.position)
			}

			// If constant-time comparison is NOT used, early differences would return faster
			// While we can't easily test timing here, we verify all positions fail equally
		})
	}

	t.Log("✓ Constant-time comparison: All signature positions validated equally")
	t.Log("  Note: crypto/subtle.ConstantTimeCompare is used in implementation")
}

// TestPrivateKey_IsCriticalToSecurity verifies private key is essential
func TestPrivateKey_IsCriticalToSecurity(t *testing.T) {
	cfg1 := &Config{PrivateKey: "secret_key_1"}
	cfg2 := &Config{PrivateKey: "secret_key_2"}

	// Generate state with key1
	state, userAgentKey, err := GenerateState(cfg1, "data")
	if err != nil {
		t.Fatalf("Failed to generate state: %v", err)
	}

	// Should verify with key1
	_, err = VerifyState(cfg1, state, userAgentKey)
	if err != nil {
		t.Fatalf("State should be valid with correct private key")
	}

	// Should NOT verify with key2 (different private key)
	_, err = VerifyState(cfg2, state, userAgentKey)
	if err == nil {
		t.Error("SECURITY VULNERABILITY: State verified with different private key!")
	}

	// This proves that the private key is cryptographically involved in the signature
	t.Log("✓ Private key security verified: Different keys produce incompatible signatures")
}

// TestUserAgentKey_ProperlyIntegratedInSignature verifies userAgentKey is in payload
func TestUserAgentKey_ProperlyIntegratedInSignature(t *testing.T) {
	cfg := testConfig()

	// Generate two states with same data but different userAgentKeys (implicit)
	state1, key1, err := GenerateState(cfg, "same_data")
	if err != nil {
		t.Fatalf("Failed to generate state1: %v", err)
	}

	state2, key2, err := GenerateState(cfg, "same_data")
	if err != nil {
		t.Fatalf("Failed to generate state2: %v", err)
	}

	// The states should be different even with same data (different random and keys)
	if state1 == state2 {
		t.Error("States should differ due to different random values")
	}

	// Each state should only verify with its own key
	_, err1 := VerifyState(cfg, state1, key1)
	_, err2 := VerifyState(cfg, state2, key2)

	if err1 != nil || err2 != nil {
		t.Fatal("States should be valid with their own keys")
	}

	// Cross-verification should fail
	_, err1 = VerifyState(cfg, state1, key2)
	_, err2 = VerifyState(cfg, state2, key1)

	if err1 == nil || err2 == nil {
		t.Error("SECURITY VULNERABILITY: userAgentKey not properly integrated in signature!")
	}

	t.Log("✓ UserAgentKey integration verified: Each state bound to its specific key")
}
