package config

import (
	"designs/app/common/log"
	"fmt"
	"strconv"
	"strings"

	"github.com/pkg/errors"
)

type ConfigRootFunc func() *ConfigNode

type ConfigEnv [2]string
type ConfigNode map[string]interface{}
type ConfigRoot map[string]ConfigRootFunc

var EnvMap map[string]string
var Root = make(map[string]*ConfigNode)

func env(envField, defaultValue string) string {
	if envValue, ok := EnvMap[envField]; ok {
		return envValue
	} else {
		return defaultValue
	}
}

// 初始化配置信息
func InitConfig(envMap map[string]string, root *ConfigRoot) error {
	EnvMap = envMap
	for k, v := range *root {
		Root[k] = v()
	}

	return nil
}

// 打印配置信息
func PrintConfig() {
	for k, v := range Root {
		printConfigNode(k, v)
	}
}

func printConfigNode(prefix string, node *ConfigNode) {
	for k, v := range *node {
		if strValue, ok := v.(string); ok {
			fmt.Printf("%-50s%s\n", prefix+"."+k, strValue)
		} else if _, ok := v.(*ConfigNode); ok {
			printConfigNode(prefix+"."+k, v.(*ConfigNode))
		} else {
			fmt.Printf("%-50s%+v\n", prefix+"."+k, v)
		}
	}
}

// 获取配置信息
func Get(k string) string {
	kList := strings.Split(k, ".")
	if len(kList) < 2 {
		log.Errorf("get error config: %s", k)
		return ""
	}

	//获取第一个节点[1,1]
	node, ok := Root[kList[0]]
	if !ok {
		log.Errorf("get not exist config: %s", k)
		return ""
	}

	//循环[2, n-1]
	for _, v := range kList[1 : len(kList)-1] {
		if n, ok := (*node)[v]; ok {
			if nn, ok := n.(*ConfigNode); ok {
				node = nn
			} else {
				log.Errorf("get not exist config: %s", k)
				return ""
			}
		} else {
			log.Errorf("get not exist config: %s", k)
			return ""
		}
	}

	//最后一个节点[n,n]
	if n, ok := (*node)[kList[len(kList)-1]]; ok {
		if sv, ok := n.(string); ok {
			return sv
		} else {
			log.Errorf("get not exist config: %s", k)
			return ""
		}
	}

	log.Errorf("get not exist config: %s", k)
	return ""
}

func GetNode(k string) (*ConfigNode, error) {
	kList := strings.Split(k, ".")

	//获取第一个节点[1,1]
	node, ok := Root[kList[0]]
	if !ok {
		log.Errorf("get not exist config: %s", k)
		return nil, errors.New("get not exist config")
	}

	//循环[2, n-1]
	if len(kList) > 2 {
		for _, v := range kList[1 : len(kList)-1] {
			if n, ok := (*node)[v]; ok {
				if nn, ok := n.(*ConfigNode); ok {
					node = nn
				} else {
					log.Errorf("get not exist config: %s", k)
					return nil, errors.New("get not exist config")
				}
			} else {
				log.Errorf("get not exist config: %s", k)
				return nil, errors.New("get not exist config")
			}
		}
	}

	return node, nil
}

// 获取配置信息，并转成int
func GetInt(k string) int {
	v := Get(k)
	if v == "" {
		return 0
	}

	i, err := strconv.Atoi(v)
	if err != nil {
		log.Warnf("can not convert %s, value %s to int", k, v)
		return 0
	}

	return i
}

func GetInt64(k string) int64 {
	return int64(GetInt(k))
}

// 获取配置信息，并转成bool
func GetBool(k string) bool {
	v := Get(k)
	if v == "" {
		return false
	}

	return v == "true"
}
