func InitializeWithDefaults(name, envPrefix string, defaults interface{}, opts ...Option) *Manager {
	return Initialize(name, envPrefix, defaults, append(DefaultOptions, opts...)...)
}
InitializeWithDefaults is the same as Initialize but it sets some sane default options (see DefaultOptions)
alongside the passed in options.
package config
import (
	"crypto/tls"
	"fmt"
	"io"
	"os"
	"reflect"
	"sort"
	"strings"
	"time"
	"github.com/mitchellh/mapstructure"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
	"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
	"go.thethings.network/lorawan-stack/v3/pkg/types"
)
const TimeFormat = time.RFC3339Nano
type Manager struct {
	name         string
	envPrefix    string
	viper        *viper.Viper
	flags        *pflag.FlagSet
	replacer     *strings.Replacer
	defaults     interface{}
	defaultPaths []string
	configFlag   string
	dataDirFlag  string
}
func (m *Manager) Flags() *pflag.FlagSet {
	return m.flags
}
func EnvKeyReplacer(r *strings.Replacer) Option {
	return func(m *Manager) {
		m.viper.SetEnvKeyReplacer(r)
		m.replacer = r
	}
}
func (m *Manager) AllEnvironment() []string {
	keys := m.AllKeys()
	env := make([]string, 0, len(keys))
	for _, key := range keys {
		env = append(env, m.EnvironmentForKey(key))
	}
	return env
}
func (m *Manager) AllKeys() []string {
	keys := m.viper.AllKeys()
	sort.Strings(keys)
	return keys
}
func (m *Manager) EnvironmentForKey(key string) string {
	return strings.ToUpper(m.replacer.Replace(m.envPrefix + "." + key))
}
func (m *Manager) Get(key string) interface{} {
	return m.viper.Get(key)
}
type Option func(m *Manager)
func WithDeprecatedFlag(name, usageMessage string) Option {
	return func(m *Manager) {
		m.flags.MarkDeprecated(name, usageMessage)
	}
}
var DefaultOptions = []Option{
	EnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")),
	WithConfigFileFlag("config"),
}
func Initialize(name, envPrefix string, defaults interface{}, opts ...Option) *Manager {
	m := &Manager{
		name:      name,
		envPrefix: envPrefix,
		viper:     viper.New(),
		flags:     pflag.NewFlagSet(name, pflag.ExitOnError),
		replacer:  strings.NewReplacer(),
		defaults:  defaults,
	}
	m.viper.SetTypeByDefaultValue(true)
	m.viper.SetConfigName(name)
	m.viper.SetConfigType("yml")
	m.viper.AllowEmptyEnv(true)
	m.viper.SetEnvPrefix(envPrefix)
	m.viper.AutomaticEnv()
	m.viper.AddConfigPath(".")
	m.flags.SetInterspersed(true)
	if defaults != nil {
		m.setDefaults("", m.flags, defaults)
	}
	for _, opt := range opts {
		opt(m)
	}
	err := m.viper.BindPFlags(m.flags)
	if err != nil {
		panic(err)
	}
	return m
}
func (m *Manager) WithConfig(defaults interface{}) *pflag.FlagSet {
	flags := pflag.NewFlagSet(m.name, pflag.ExitOnError)
	flags.AddFlagSet(m.flags)
	if defaults != nil {
		m.setDefaults("", flags, defaults)
	}
	err := m.viper.BindPFlags(flags)
	if err != nil {
		panic(err)
	}
	return flags
}