package config

import (
	"os"
	"testing"

	"go.uber.org/zap/zaptest"
)

// NewTestConfig crée une configuration de test avec valeurs par défaut (T0035)
// Cette fonction facilite la création de configurations de test sans nécessiter
// une base de données ou Redis réels, parfait pour les tests unitaires
func NewTestConfig(t *testing.T) *Config {
	// Créer un logger de test
	logger := zaptest.NewLogger(t)

	return &Config{
		AppPort:         8080,
		JWTSecret:       "test-jwt-secret-key-minimum-32-characters-long",
		DatabaseURL:     "postgres://test:test@localhost:5432/test_db",
		RedisURL:        "redis://localhost:6379/0",
		CORSOrigins:     []string{"*"},
		RateLimitLimit:  100,
		RateLimitWindow: 60,
		LogLevel:        "DEBUG",
		Logger:          logger,
	}
}

// WithEnv définit temporairement une variable d'environnement pour les tests (T0035)
// Retourne une fonction de cleanup qui restaure la valeur originale (ou unset si elle n'existait pas)
// Usage:
//
//	reset := WithEnv("TEST_VAR", "test_value")
//	defer reset()
//	// ... test code ...
func WithEnv(key, value string) func() {
	oldValue := os.Getenv(key)
	os.Setenv(key, value)
	return func() {
		if oldValue == "" {
			os.Unsetenv(key)
		} else {
			os.Setenv(key, oldValue)
		}
	}
}

// ResetEnv réinitialise toutes les variables d'environnement de test couramment utilisées (T0035)
// Cette fonction nettoie les variables d'environnement après les tests pour éviter
// les interférences entre tests
func ResetEnv() {
	testVars := []string{
		"APP_ENV",
		"APP_PORT",
		"JWT_SECRET",
		"DATABASE_URL",
		"REDIS_URL",
		"CORS_ALLOWED_ORIGINS",
		"RATE_LIMIT_LIMIT",
		"RATE_LIMIT_WINDOW",
		"LOG_LEVEL",
	}
	for _, v := range testVars {
		os.Unsetenv(v)
	}
}

// WithMultipleEnv définit temporairement plusieurs variables d'environnement pour les tests (T0035)
// Retourne une fonction de cleanup qui restaure toutes les valeurs originales
// Usage:
//
//	reset := WithMultipleEnv(map[string]string{
//	  "APP_ENV": "test",
//	  "LOG_LEVEL": "DEBUG",
//	})
//	defer reset()
func WithMultipleEnv(envVars map[string]string) func() {
	// Sauvegarder les valeurs actuelles
	oldValues := make(map[string]string)
	for key := range envVars {
		oldValues[key] = os.Getenv(key)
	}

	// Définir les nouvelles valeurs
	for key, value := range envVars {
		os.Setenv(key, value)
	}

	// Retourner la fonction de cleanup
	return func() {
		for key, oldValue := range oldValues {
			if oldValue == "" {
				os.Unsetenv(key)
			} else {
				os.Setenv(key, oldValue)
			}
		}
	}
}
