package config

import (
	"os"
	"testing"
)

const historicKey = "hfb-sys-2024-secret-key-32bytes!"

func TestIsProductionEnv(t *testing.T) {
	cases := []struct {
		in   string
		want bool
	}{
		{"production", true},
		{"PRODUCTION", true},
		{"  production  ", true},
		{"development", false},
		{"", false},
		{"staging", false},
	}
	for _, c := range cases {
		if got := IsProductionEnv(c.in); got != c.want {
			t.Fatalf("IsProductionEnv(%q) = %v, want %v", c.in, got, c.want)
		}
	}
}

// TestFieldEncryptionLegacyKeyNonProductionDefaultsToHistoric 验证非生产环境未设置 legacy 时
// 回退到历史硬编码密钥（开发态零配置兼容旧密文）。
func TestFieldEncryptionLegacyKeyNonProductionDefaultsToHistoric(t *testing.T) {
	unsetEnv(t, "FIELD_ENCRYPTION_LEGACY_KEY")
	if got := fieldEncryptionLegacyKey("development"); got != historicKey {
		t.Fatalf("non-production default legacy = %q, want %q", got, historicKey)
	}
}

// TestFieldEncryptionLegacyKeyNonProductionExplicitOverride 验证非生产环境显式设置 legacy 时用该值。
func TestFieldEncryptionLegacyKeyNonProductionExplicitOverride(t *testing.T) {
	t.Setenv("FIELD_ENCRYPTION_LEGACY_KEY", "explicit-legacy-16bytes!")
	if got := fieldEncryptionLegacyKey("development"); got != "explicit-legacy-16bytes!" {
		t.Fatalf("non-production explicit legacy = %q, want explicit-legacy-16bytes!", got)
	}
}

// TestFieldEncryptionLegacyKeyProductionEmptyDisablesFallback 验证生产环境未设置/留空 legacy
// 返回空（禁用回退），而不是注入历史硬编码密钥。
// 这是密钥轮换闭环的关键：删除 env 必须真正关闭旧密钥。
func TestFieldEncryptionLegacyKeyProductionEmptyDisablesFallback(t *testing.T) {
	t.Setenv("FIELD_ENCRYPTION_LEGACY_KEY", "")
	if got := fieldEncryptionLegacyKey("production"); got != "" {
		t.Fatalf("production empty legacy = %q, want empty (fallback disabled); injecting historic key breaks rotation closure", got)
	}
}

// TestFieldEncryptionLegacyKeyProductionExplicitValue 验证生产环境显式设置 legacy 时用该值
// （轮换期间保留旧密钥解密存量）。
func TestFieldEncryptionLegacyKeyProductionExplicitValue(t *testing.T) {
	t.Setenv("FIELD_ENCRYPTION_LEGACY_KEY", "prod-old-key-32bytes-0123456789")
	if got := fieldEncryptionLegacyKey("production"); got != "prod-old-key-32bytes-0123456789" {
		t.Fatalf("production explicit legacy = %q, want prod-old-key-32bytes-0123456789", got)
	}
}

// TestValidateProductionSecurityRejectsPrimaryEqualsLegacy 验证生产环境 primary 等于 legacy 时报错。
func TestValidateProductionSecurityRejectsPrimaryEqualsLegacy(t *testing.T) {
	t.Setenv("APP_ENV", "production")
	t.Setenv("JWT_SECRET", "a-very-long-random-jwt-secret-at-least-32-bytes!!")
	t.Setenv("PAYMENT_CONFIG_ENCRYPTION_KEY", "0123456789abcdef0123456789abcdef")
	t.Setenv("FIELD_ENCRYPTION_KEY", "0123456789abcdef0123456789abcdef")
	t.Setenv("FIELD_ENCRYPTION_LEGACY_KEY", "0123456789abcdef0123456789abcdef")
	cfg := Load()
	if err := cfg.ValidateProductionSecurity(); err == nil {
		t.Fatal("ValidateProductionSecurity should reject FIELD_ENCRYPTION_KEY == LEGACY_KEY")
	}
}

// TestValidateProductionSecurityRejectsInvalidLegacyKey 验证生产环境显式设置 legacy 时也校验长度。
func TestValidateProductionSecurityRejectsInvalidLegacyKey(t *testing.T) {
	t.Setenv("APP_ENV", "PRODUCTION")
	t.Setenv("JWT_SECRET", "a-very-long-random-jwt-secret-at-least-32-bytes!!")
	t.Setenv("PAYMENT_CONFIG_ENCRYPTION_KEY", "0123456789abcdef0123456789abcdef")
	t.Setenv("FIELD_ENCRYPTION_KEY", "abcdef0123456789abcdef0123456789")
	t.Setenv("FIELD_ENCRYPTION_LEGACY_KEY", "too-short")
	cfg := Load()
	if err := cfg.ValidateProductionSecurity(); err == nil {
		t.Fatal("ValidateProductionSecurity should reject invalid FIELD_ENCRYPTION_LEGACY_KEY")
	}
}

func unsetEnv(t *testing.T, key string) {
	t.Helper()
	old, ok := os.LookupEnv(key)
	if err := os.Unsetenv(key); err != nil {
		t.Fatalf("unset %s: %v", key, err)
	}
	t.Cleanup(func() {
		if ok {
			_ = os.Setenv(key, old)
			return
		}
		_ = os.Unsetenv(key)
	})
}
