/*
Copyright © 2024 慕枫Go <mapleafgo@163.com>
*/
package cmd

import (
	"errors"
	"game-driver/config"
	"game-driver/config/game"
	"game-driver/config/wait"
	"game-driver/internal"
	"io/fs"
	"log"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var cfgFile string

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:     "game-driver",
	Version: "1.0.1",
	Short:   "A brief description of your application",
	Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	// Uncomment the following line if your bare application
	// has an action associated with it:
	Run: func(cmd *cobra.Command, args []string) {
		internal.Run()
	},
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	err := rootCmd.Execute()
	if err != nil {
		os.Exit(1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "config.yml", "默认当前目录下的 config.yml")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	viper.SetConfigFile(cfgFile)
	viper.AutomaticEnv() // read in environment variables that match
	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		log.Printf("Using config file: %s", viper.ConfigFileUsed())
	} else if errors.Is(err, fs.ErrNotExist) {
		log.Printf("无法找到主配置文件: %s", viper.ConfigFileUsed())
		os.Exit(1)
	} else {
		log.Panicln("read config file error: ", err)
	}
	err := viper.Unmarshal(&config.C)
	if err != nil {
		log.Panicln("unmarshal config failed: ", err)
	}

	// 初始化游戏节点配置
	game.C = game.NewConfig(config.C.Point)
	if game.C != nil { // 如果需要游戏配置
		err = viper.UnmarshalKey("game", &game.C)
		if err != nil {
			log.Panicln("unmarshal game config failed: ", err)
		}
	}

	// 初始化游戏节点待机时配置
	wait.C = wait.NewConfig(config.C.Point)
	if wait.C != nil { // 如果需要游戏配置
		err = viper.UnmarshalKey("wait", &wait.C)
		if err != nil {
			log.Panicln("unmarshal wait config failed: ", err)
		}
	}
}
