package initialize

import (
	"gitee.ltd/lxh/wechat-robot/internal/config"
	"gitee.ltd/lxh/wechat-robot/internal/docker"
	"gitee.ltd/lxh/wechat-robot/internal/minio"
	"gitee.ltd/lxh/wechat-robot/internal/model"
	"gitee.ltd/lxh/wechat-robot/internal/redis"
	"github.com/fsnotify/fsnotify"
	"github.com/gofiber/fiber/v2/log"
	"github.com/spf13/viper"
	"os"
	"strings"
)

// initConfig
// @description: 初始化配置文件
func initConfig() {
	viper.SetConfigName("config")

	// 检查是否有环境变量指定使用开发配置
	if os.Getenv("APP_ENV") == "development" {
		viper.SetConfigName("config.dev")
	}

	viper.SetConfigType("yaml")
	viper.AddConfigPath("./configs")
	viper.AddConfigPath(".")

	// 环境变量覆盖
	viper.AutomaticEnv()
	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

	// 读取配置文件
	if err := viper.ReadInConfig(); err != nil {
		log.Panicf("配置文件读取失败: %v", err)
		return
	}
	// 绑定到
	if err := viper.Unmarshal(&config.Scd); err != nil {
		log.Panicf("配置文件解析失败: %v", err)
		return
	}
	log.Debugf("配置文件解析成功: %+v", config.Scd)
	if err := config.Scd.Validate(); err != nil {
		log.Panicf("配置文件验证失败: %v", err)
		return
	}

	// 下面的代码是配置变动之后自动刷新的
	viper.OnConfigChange(func(e fsnotify.Event) {
		// 绑定配置文件
		if err := viper.Unmarshal(&config.Scd); err != nil {
			log.Errorf("配置文件更新失败: %v", err)
		} else if err = config.Scd.Validate(); err != nil {
			log.Errorf("配置文件验证失败: %v", err)
		} else {
			// 初始化数据库连接等操作
			model.InitDB()          // 1. 初始化数据库
			redis.InitRedisClient() // 2. 初始化Redis
			minio.Init()            // 3. 初始化Minio
			docker.InitClient()     // 4. 初始化Docker客户端
		}
	})
	// 监听变动
	viper.WatchConfig()
}
