package config import ( "fmt" "os" "strconv" "strings" ) // Config holds all configuration for the application type Config struct { Server ServerConfig Log LogConfig Metrics MetricsConfig } // ServerConfig holds server-related configuration type ServerConfig struct { GRPCPort string HTTPPort string } // LogConfig holds logging configuration type LogConfig struct { Level string Format string } // MetricsConfig holds metrics configuration type MetricsConfig struct { Enabled bool } // Load loads configuration from environment variables with defaults func Load() *Config { return &Config{ Server: ServerConfig{ GRPCPort: getEnv("SERVER_GRPC_PORT", "8080"), HTTPPort: getEnv("SERVER_HTTP_PORT", "8090"), }, Log: LogConfig{ Level: strings.ToLower(getEnv("LOG_LEVEL", "info")), Format: strings.ToLower(getEnv("LOG_FORMAT", "json")), }, Metrics: MetricsConfig{ Enabled: getEnvBool("METRICS_ENABLED", true), }, } } // Validate validates the configuration func (c *Config) Validate() error { if c.Server.GRPCPort == "" { return fmt.Errorf("gRPC port cannot be empty") } if c.Server.HTTPPort == "" { return fmt.Errorf("HTTP port cannot be empty") } if c.Server.GRPCPort == c.Server.HTTPPort { return fmt.Errorf("gRPC and HTTP ports cannot be the same") } validLogLevels := map[string]bool{ "debug": true, "info": true, "warn": true, "error": true, } if !validLogLevels[c.Log.Level] { return fmt.Errorf("invalid log level: %s", c.Log.Level) } validLogFormats := map[string]bool{ "json": true, "text": true, } if !validLogFormats[c.Log.Format] { return fmt.Errorf("invalid log format: %s", c.Log.Format) } return nil } // getEnv gets an environment variable or returns a default value func getEnv(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue } // getEnvBool gets a boolean environment variable or returns a default value func getEnvBool(key string, defaultValue bool) bool { if value := os.Getenv(key); value != "" { if parsed, err := strconv.ParseBool(value); err == nil { return parsed } } return defaultValue }