package main

import (
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	gormLogger "gorm.io/gorm/logger"
	"iot_manager_service/app/data/controller"
	data "iot_manager_service/app/data/dao"
	device "iot_manager_service/app/device/dao"
	multimedia "iot_manager_service/app/multimedia/dao"
	operation "iot_manager_service/app/operation/dao"
	record "iot_manager_service/app/record/dao"
	system "iot_manager_service/app/system/dao"
	warn "iot_manager_service/app/warn/dao"
	"iot_manager_service/config"
	_ "iot_manager_service/config"
	"iot_manager_service/router"
	"iot_manager_service/util/cache"
	"iot_manager_service/util/logger"
	"iot_manager_service/util/minio"
	"net/url"
	"time"
)

func main() {
	cfg := config.Instance()
	// 只在本地开调试模式
	if cfg.Logger.DbShowLog == 1 {
		gin.SetMode(gin.DebugMode)
	} else {
		gin.SetMode(gin.ReleaseMode)
	}
	logger.InitLog()
	// 实例化配置
	initDB()
	err := cache.InitRedis()
	if err != nil {
		panic(err)
	}
	minio.InitMinio()
	controller.CalcTask()
	engine := gin.Default()

	router.InitRouter(engine)
	if cfg.Logger.DbShowLog == 1 {
		println(gin.DebugMode + "当前为开发环境，会产生较多调试日志")
	} else {
		println(gin.ReleaseMode)
	}
	_ = engine.Run(config.Instance().Server.Address)

}

func initDB() {
	cfg := config.Instance()
	dsn := cfg.Database.User + ":" + cfg.Database.Password + "@tcp(" + cfg.Database.Host + ":" + cfg.Database.Port + ")/" + cfg.Database.Name + "?charset=utf8&parseTime=True" + "&loc=" + url.QueryEscape(cfg.Database.Timezone)
	// 如果是本地开发环境 则 打印gorm 查询日志到控制台
	logCfg := gormLogger.Interface(nil)
	if cfg.Logger.DbShowLog == 1 {
		logCfg = gormLogger.Default
	} else {
		logCfg = gormLogger.New(logger.Logger, gormLogger.Config{
			SlowThreshold: 200 * time.Millisecond,
			LogLevel:      gormLogger.Error,
			Colorful:      true,
		})
	}

	//logCfg = gormLogger.Default

	db, err := gorm.Open(mysql.New(mysql.Config{
		DSN: dsn,
	}), &gorm.Config{Logger: logCfg})
	if err != nil {
		panic(err)
	} else {
		sqlDB, err := db.DB()
		if err != nil {
			panic(err)
		}
		if err := sqlDB.Ping(); err != nil {
			panic(err)
		}
		sqlDB.SetMaxOpenConns(32)
		sqlDB.SetMaxOpenConns(5)
		sqlDB.SetConnMaxLifetime(time.Hour * 4) //括号里面是超时时间，要小于数据库的超时时间  返回 invalid connection的问题
	}
	device.InitDB(db)
	system.InitDB(db)
	multimedia.InitDB(db)
	data.InitDB(db)
	record.InitDB(db)
	warn.InitDB(db)
	operation.InitDB(db)

}
