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"
	"os"
	"time"
)

func main() {
	// 只在本地开调试模式
	if isDevEnv() {
		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 isDevEnv() {
		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)
	logCfg := gormLogger.New(logger.Logger, gormLogger.Config{
		SlowThreshold: 200 * time.Millisecond,
		LogLevel:      gormLogger.Info,
		Colorful:      true,
	})
	// 如果是本地开发环境 则 打印gorm 查询日志到控制台
	if isDevEnv() {
		logCfg = gormLogger.Default
	}
	//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)

}

// isDevEnv 是否开发环境 本地开发需要添加环境变量
// 		[windows] CMD下执行 setx "DEV_ENV" "1"
//		[linux] export DEV_ENV="1"
func isDevEnv() bool {
	//return true
	if os.Getenv("DEV_ENV") == "1" {
		return true
	}
	return false
}