package config

import (
	"github.com/creasty/defaults"
	"github.com/go-playground/validator/v10"
	"github.com/pingcap/errors"
	"github.com/spf13/viper"
)

// @Time    : 2022/11/14 4:56 PM
// @Author  : lvhongmeng

var validate = validator.New()

func Global() *CentralConfig {
	return globalConf
}

// InitConfig parse the central configuration file and init the global config var
func InitConfig(path string) error {
	viper.SetConfigFile(path)
	viper.AutomaticEnv() // for M2M env variables
	err := viper.ReadInConfig()
	if err != nil {
		return err
	}
	/*
		err = LoadRemote()
		if err != nil {
			log.Warn("load remote config failed, just ignore it in persnonal project", zap.Error(err))
		}
	*/

	err = NormalizeConfig()
	if err != nil {
		return err
	}

	return nil
}

func NormalizeConfig() error {
	config := &CentralConfig{}

	err := NormalizeConfigDefaults(config)
	if err != nil {
		return err
	}
	err = NormalizeConfigSetup(config)
	if err != nil {
		return err
	}
	err = NormalizeConfigValidate(config)
	if err != nil {
		return err
	}
	globalConf = config
	return nil
}

func NormalizeConfigDefaults(config *CentralConfig) error {
	return defaults.Set(config)
}

func NormalizeConfigSetup(config *CentralConfig) error {
	err := viper.Unmarshal(config)
	if err != nil {
		return errors.Annotate(err, "failed unmarshal from viper")
	}
	return nil
}

func NormalizeConfigValidate(config *CentralConfig) error {
	// validate the values
	if err := validate.Struct(config); err != nil {
		return errors.Annotate(err, "failed to validate the config values")
	}
	return nil
}
