package config

import (
	"context"
	"fmt"
	"git.icechen.cn/monorepo/backend/app/brahma/api/murder/internal/error_process"
	ctxLogger "github.com/luizsuper/ctxLoggers"
	clientV3 "go.etcd.io/etcd/client/v3"
	"go.uber.org/zap"
	"os"
	"strings"
	"time"
)

const (
	DsnPre         = "dsn"
	Local          = "local"
	Env            = "env"
	Configs        = "config"
	Etcd           = "etcd"
	EtcdEnd        = "endpoints"
	EtcdEndDefault = "127.0.0.1:2379"
	Port
	PortDefault = "8080"
)

const (
	TestDB = "taihe"
)

type Config map[string]string

var (
	client    *clientV3.Client
	configMap = make(Config, 0)
	config    clientV3.Config
	err       error
)

func GetConfig() {
	env := GetEnvDefault(Env, Local)
	host := GetEnvDefault(Configs, Etcd)
	switch host {
	case Etcd:
		etcdReader(env)
	}
}

func etcdReader(env string) {
	kv := clientV3.NewKV(client)
	defer client.Close()
	ctx, cancel := context.WithTimeout(context.TODO(), time.Second*3)
	defer cancel()
	if getResp, err := kv.Get(ctx, fmt.Sprintf("/config/%v/", env), clientV3.WithPrefix()); err == nil {
		for _, v := range getResp.Kvs {
			configMap[string(v.Key)] = string(v.Value)
		}
	} else {
		ctxLogger.Error(nil, error_process.EtcReadError, zap.String("", err.Error()))
		os.Exit(-1)
	}
}

func GetConfigMap() Config {
	return configMap
}

func GetConfigKey(key string) string {
	configs := GetEnvDefault(Configs, "")
	env := GetEnvDefault(Env, "")
	switch configs {
	case Etcd:
		fmt.Printf("/config/%v/%v", env, key)
		return fmt.Sprintf("/config/%v/%v", env, key)
	default:
		return ""
	}
}
func init() {
	connect()
}

func connect() {
	envDefault := GetEnvDefault(EtcdEnd, EtcdEndDefault)
	ends := strings.Split(envDefault, ",")
	config = clientV3.Config{
		Endpoints:   ends,
		DialTimeout: 5 * time.Second,
	}
	if client, err = clientV3.New(config); err != nil {
		ctxLogger.FError(nil, error_process.EtcConnError, zap.String("", err.Error()))
		os.Exit(-1)
	}
}

func GetEnvDefault(key, defVal string) string {
	val, ex := os.LookupEnv(key)
	if !ex {
		os.Setenv(key, defVal)
		return defVal
	}
	return val
}