package config import ( "fmt" "time" "github.com/rs/zerolog/log" "github.com/spf13/viper" ) // Config represents the application configuration type Config struct { Server struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` } Shutdown struct { Timeout time.Duration `mapstructure:"timeout"` } } // LoadConfig loads configuration from environment variables and defaults func LoadConfig() (*Config, error) { v := viper.New() // Set default values v.SetDefault("server.host", "0.0.0.0") v.SetDefault("server.port", 8080) v.SetDefault("shutdown.timeout", 30*time.Second) // Bind environment variables v.AutomaticEnv() v.SetEnvPrefix("DLC") // DanceLessonsCoach prefix v.BindEnv("server.host", "DLC_SERVER_HOST") v.BindEnv("server.port", "DLC_SERVER_PORT") v.BindEnv("shutdown.timeout", "DLC_SHUTDOWN_TIMEOUT") // Unmarshal into Config struct var config Config if err := v.Unmarshal(&config); err != nil { log.Error().Err(err).Msg("Failed to unmarshal config") return nil, fmt.Errorf("config unmarshal error: %w", err) } log.Info(). Str("host", config.Server.Host). Int("port", config.Server.Port). Dur("shutdown_timeout", config.Shutdown.Timeout). Msg("Configuration loaded") return &config, nil } // GetServerAddress returns the formatted server address (host:port) func (c *Config) GetServerAddress() string { return fmt.Sprintf("%s:%d", c.Server.Host, c.Server.Port) }