package conf

import (
	"strings"

	"github.com/spf13/viper"
)

var (
	//错误字符串切片长度
	LenStackBuf   = 4096
	ConsolePrompt = "grave# "
	// pprof文件路径
	ProfilePath string
)

// Config is a wrapper around a viper config
type Config struct {
	*viper.Viper
}

// NewConfig creates a new config with a given viper config if given
func NewConfig(conf *viper.Viper) *Config {
	var cfg *viper.Viper
	if conf == nil {
		cfg = viper.New()
	} else {
		cfg = conf
	}
	cfg.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	cfg.AutomaticEnv()
	c := &Config{Viper: cfg}
	c.fillDefaultValues()

	// c.config.AddConfigPath("./")
	// c.config.SetConfigFile("gate.json")
	// c.config.WriteConfig()

	ProfilePath = cfg.GetString("console.profilepath")
	return c
}

type ConnAddr struct {
	Addr string
	Tag  int
}

func (c *Config) fillDefaultValues() {
	defaultsMap := map[string]interface{}{

		"mysql.datasource": "root:123456@tcp(127.0.0.1:3306)/grave?charset=utf8&timeout=10s",

		"wx.appid":      "wx64db79a6a7bcf3f4",
		"wx.appkey":     "3e25707fff474fca653621861f0fecc9",
		"wx.code2idurl": "https://api.weixin.qq.com/sns/jscode2session",

		"qq.appid":      "wx64db79a6a7bcf3f4",
		"qq.appkey":     "3e25707fff474fca653621861f0fecc9",
		"qq.code2idurl": "https://api.weixin.qq.com/sns/jscode2session",

		"http.listenaddr": ":10108", //

		"cluster.id":         "123",
		"cluster.servertype": "login",

		//
		"gate.maxconnnum":      20000,           //最大连接数
		"gate.pendingwritenum": 2000,            //
		"gate.maxmsglen":       5 * 1024 * 1024, //
		"gate.wsaddr":          "",              // :10110
		"gate.httptimeout":     "10s",           //
		"gate.certfile":        "",              //
		"gate.keyfile":         "",
		"gate.tcpaddr":         "",    //监听地址 :10111
		"gate.lenmsglen":       4,     //
		"gate.littleendian":    false, //

		"skeleton.golen":              10000, //
		"skeleton.timerdispatcherlen": 10000, //
		"skeleton.asyncalllen":        70000, //本机RPC调用
		"skeleton.chanrpclen":         70000, //路由消息

		"console.profilepath":   "", //监测文件名
		"console.consoleport":   0,
		"console.consoleprompt": "grave# ", //控制台提示字符

		"cluster.listenaddr":      "",           //:10112
		"cluster.connaddrs":       []ConnAddr{}, //[]ConnAddr{{Tag: 1, Addr: "127.0.0.1:10112"}, {Tag: 2, Addr: "127.0.0.1:10113"}}
		"cluster.pendingwritenum": 70000,        //发送数据
		"cluster.connectinterval": "3s",

		"grave.nats.connectiontimeout":      "2s",
		"grave.nats.maxreconnectionretries": 15,
		"grave.nats.requesttimeout":         "5s",
		"grave.nats.connect":                "nats://localhost:4222",
		"grave.nats.messages":               75,
		"grave.nats.push":                   100,

		//"grave.nats.connectiontimeout":      "2s",
		//"grave.nats.maxreconnectionretries": 15,
	}

	for param := range defaultsMap {
		if c.Get(param) == nil {
			c.SetDefault(param, defaultsMap[param])
		}
	}
}

// // GetDuration returns a duration from the inner config
// func (c *Config) GetDuration(s string) time.Duration {
// 	return c.GetDuration(s)
// }

// // GetString returns a string from the inner config
// func (c *Config) GetString(s string) string {
// 	return c.GetString(s)
// }

// // GetInt returns an int from the inner config
// func (c *Config) GetInt(s string) int {
// 	return c.config.GetInt(s)
// }

// // GetUint32 returns an int from the inner config
// func (c *Config) GetUint32(s string) uint32 {
// 	return c.config.GetUint32(s)
// }

// // GetBool returns an boolean from the inner config
// func (c *Config) GetBool(s string) bool {
// 	return c.config.GetBool(s)
// }

// // GetStringSlice returns a string slice from the inner config
// func (c *Config) GetStringSlice(s string) []string {
// 	return c.config.GetStringSlice(s)
// }

// // Get returns an interface from the inner config
// func (c *Config) Get(s string) interface{} {
// 	return c.config.Get(s)
// }

// // GetStringMapString returns a string map string from the inner config
// func (c *Config) GetStringMapString(s string) map[string]string {
// 	return c.config.GetStringMapString(s)
// }

// // UnmarshalKey unmarshals key into v
// func (c *Config) UnmarshalKey(s string, v interface{}) error {
// 	return c.config.UnmarshalKey(s, v)
// }

// func (c *Config) Sub(s string) *viper.Viper {
// 	return c.config.Sub(s)
// }
