package main

/*
1. 算法清理可以用仿真云平台的调度系统
*/

import (
	"cicv-data-closedloop/amd64/dispatch_server/package/global"
	"cicv-data-closedloop/amd64/dispatch_server/package/handler"
	"cicv-data-closedloop/amd64/dispatch_server/package/infra"
	"cicv-data-closedloop/amd64/dispatch_server/package/service"
	"cicv-data-closedloop/common/gin/middleware"
	"cicv-data-closedloop/common/util"
	_ "embed"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"os"
)

func init() {
	// 1 解析YAML内容
	infra.InitApplication()
	// 2 初始化 日志
	infra.InitLog(infra.ApplicationYaml.Log.Dir, infra.ApplicationYaml.Log.Prefix)
	// 3 初始化 阿里云oss 客户端
	infra.InitOss(
		infra.ApplicationYaml.Oss.IsUseCname,
		infra.ApplicationYaml.Oss.Endpoint,
		infra.ApplicationYaml.Oss.AccessKeyId,
		infra.ApplicationYaml.Oss.AccessKeySecret,
		infra.ApplicationYaml.Oss.BucketName,
	)
	// 4 初始化 Redis 客户端
	infra.InitRedisClient(
		infra.ApplicationYaml.Redis.Addr,
		infra.ApplicationYaml.Redis.Password,
		infra.ApplicationYaml.Redis.Db,
	)
	// 5 将 gpu-node-list 写入redis
	err := infra.GlobalRedisClient.Del(global.KeyGpuNodeList).Err()
	if err != nil {
		infra.GlobalLogger.Error("程序崩溃。gpu-node-list 初始化失败1：", err)
		os.Exit(-1)
	}
	for _, gpuNode := range infra.ApplicationYaml.GpuNodeList {
		gpuNodeJson, err := json.MarshalIndent(gpuNode, "", "    ")
		if err != nil {
			infra.GlobalLogger.Error("程序崩溃。gpu-node-list 初始化失败2：", err)
			os.Exit(-1)
		}
		_, err = infra.GlobalRedisClient.RPush("gpu-node-list", gpuNodeJson).Result()
		if err != nil {
			infra.GlobalLogger.Error("程序崩溃。gpu-node-list 初始化失败3：", err)
			os.Exit(-1)
		}
	}

	// 6 初始化 kafka 客户端
	infra.InitKafkaProducer(infra.ApplicationYaml.Kafka.Broker)

}

func main() {

	// 启动任务处理进程
	go service.RunWaitingUser()
	go service.RunWaitingCluster()

	// 启动 web 服务器
	router := gin.Default()
	//router.Use(commonHandler.ValidateHeaders()) // todo 暂时不需要校验
	router.Use(middleware.Cors()) // 解决cors
	api1 := router.Group(infra.ApplicationYaml.Web.RoutePrefix)
	api1.POST("/start-project", handler.StartProject)
	api2 := router.Group("/simulation/resource/scheduler")
	api2.POST("/confirm", handler.Confirm)
	api2.POST("/tick", handler.Tick)
	api2.POST("/state", handler.State)
	err := router.Run(":" + infra.ApplicationYaml.Web.Port)
	if err != nil {
		infra.GlobalLogger.Error("程序崩溃，监听端口 " + util.ToString(infra.ApplicationYaml.Web.Port) + " 失败。")
		os.Exit(-1)
	}
}
