package config

import (
	"reflect"
	"strconv"
	"time"

	"example.com/golang-base/internal/log"
)

// Config uses struct tags to configure the application.
// (default) Default value to be used if unset or not defined.
// (ignored) Don't process the current tag.
// (info) String to be presented to the user on -help use.
// (secret) If set to true, hide the value from being output on start-up.
// (env) environment variable to be used if not set on command line.
type Config struct {
	// time configuration
	TimeFormat    string         `default:"2006-01-02 15:04:05" env:"time_format"`
	TimeZoneLocal string         `default:"America/Chicago"     env:"time_zone"`
	TZLocal       *time.Location `ignored:"true"`
	TZUTC         *time.Location `ignored:"true"`

	// logging
	LogLevel int `default:"50" env:"log_level"`

	// webserver
	WebServerPort         int    `default:"8080"    env:"webserver_port"`
	WebServerIP           string `default:"0.0.0.0" env:"webserver_ip"`
	WebServerReadTimeout  int    `default:"5"       env:"webserver_read_timeout"`
	WebServerWriteTimeout int    `default:"1"       env:"webserver_write_timeout"`
	WebServerIdleTimeout  int    `default:"2"       env:"webserver_idle_timeout"`
}

// New initializes the config variable for use with a prepared set of defaults.
func New() Config {
	return Config{}
}

func printRunningConfig(cfg *Config, cfgInfo []structInfo) {
	var logRunningConfiguration string = "Running Configuration"

	for _, info := range cfgInfo {
		if info.Secret {
			log.Debug(logRunningConfiguration, info.Name, "REDACTED")
		} else {
			switch info.Type.String() {
			case "string":
				p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*string)
				log.Debug(logRunningConfiguration, info.Alt, *p)
			case "bool":
				p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*bool)
				log.Debug(logRunningConfiguration, info.Alt, strconv.FormatBool(*p))
			case "int":
				p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*int)
				log.Debug(logRunningConfiguration, info.Alt, strconv.FormatInt(int64(*p), 10))
			}
		}
	}
}