package dao

import (
	"fengkuangGameServerJob/pkg/setting"
	"fmt"
	"github.com/go-redis/redis"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
	"time"
)

var (
	db  *gorm.DB      //mysql
	rdb *redis.Client //redis
)

const (
	MsgNotifyListKey     = "msgNotify"                //消息通知的队列list
	MountMissionKey      = "mountMission"             //坐骑任务zSet
	ResourceChangeLogKey = "resourceChange"           //资源变动日志list
	SysConfKey           = "sysConfForGo"             //系统配置has
	EjectPackIconLiveKey = "ejectPackIconLive"        //弹出礼包icon的生存周期(有序集合)
	StationNearBy        = "stationNearBy"            //跑商查找附近车队(集合)
	LoginToken           = "login:Token"              //登录的令牌信息(hash)
	LoginTcp             = "login:NewestTcp"          //登录的最新tcp信息(hash)
	LoginBlacklist       = "login:blacklist"          //登录的黑名单(集合)
	LoginRate            = "login:rate:%s"            //登录接口请求速率(%s是ip)
	LoginNewestServer    = "login:newestServer"       //登录获取最新的服务器
	LoginServer          = "login:Server:%s"          //登录的选服(%s是appid)
	MsgNotifyListNew     = "msgNotify"                //新的消息有序集合
	MsgNotifyContentNew  = "msgNotifyContent"         //新的消息的主要内容
	MiniGameSecrets      = "miniGame:Secrets"         //小游戏的密钥(hash)
	OpenIdOk             = "miniGame:OpenId:%s:ok"    //校验成功的openid(集合,%s是appid)
	OpenIdWrong          = "miniGame:OpenId:%s:wrong" //校验失败的openid(集合,%s是appid)
	Notice               = "notice"                   //消息缓存
	HomePageNewestServer = "homepage:newestServer"    //首页缓存最新的区服
	HomePageGroupNum     = "homepage:serverGroupNum"  //首页缓存区服分组数量
	BlackList1           = "chat:blackList1"          //新的黑名单
	GrayPrefix           = "gray:"                    //灰度的前缀
	IsNewUser            = "users:isNew:"             //是否是新用户，判断用户是否进戳爆还是进0.1(这个要一直保留)
	IsOldUser            = "users:isOld:"             //是否是老用户,这个保留一天即可
)

// DB 返回db的连接
func DB() *gorm.DB {
	return db
}

// Redis 获取redis的链接
func Redis() *redis.Client {
	return rdb
}

// InitDBEngine 初始化数据库链接
func InitDBEngine(cfg *setting.DBSettingsS) (err error) {
	dsn := "%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=%t&loc=Local"
	//db链接参数
	dsn = fmt.Sprintf(dsn,
		cfg.UserName,
		cfg.PassWord,
		cfg.Host,
		cfg.Port,
		cfg.DB,
		cfg.Charset,
		cfg.ParseTime,
	)
	//gorm的额外配置
	extraConf := &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:   cfg.Prefix, //设置表前缀
			SingularTable: true,       //表名称不使用复数
		},
		PrepareStmt: true, //全局模式，所有 DB 操作都会创建并缓存预编译语句
	}
	//设置是否打印sql
	if cfg.Log == true {
		extraConf.Logger = logger.Default.LogMode(logger.Info)
	}
	//连接数据库
	db, err = gorm.Open(mysql.Open(dsn), extraConf)
	if err != nil {
		return err
	}
	sqlDb, err := db.DB()
	if err != nil {
		return err
	}
	//设置打开数据库链接的最大数量
	sqlDb.SetMaxOpenConns(cfg.MaxOpenConns)
	//设置空闲连接池中链接的最大数量
	sqlDb.SetMaxIdleConns(cfg.MaxIdleConns)
	//设置链接可复用的最大时间
	sqlDb.SetConnMaxLifetime(time.Minute * time.Duration(cfg.MaxLifetime))
	return err
}

// InitRDB 初始化redis
func InitRDB(cfg *setting.RedisSettingsS) (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     cfg.Addr,
		DB:       cfg.DB,
		Password: cfg.Auth,
	})
	_, err = rdb.Ping().Result()
	return
}
