package dao

import (
	"DataShare/global"
	"DataShare/model"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"strconv"
	"time"
)

//Save token metadata to Redis
func CreateAuth(certKey string, td *model.TokenDetails) error {

	tokenExpire := global.SystemConfig.Redis.Cache.TokenExpire
	atCreated, err := global.RedisClient.Set(global.RedisDataShare+":"+"auth:"+td.TokenUuid, certKey, time.Second * time.Duration(tokenExpire)).Result()
	if err != nil {
		return err
	}
	refrushTokenExpire := global.SystemConfig.Redis.Cache.RefrushTokenExpire
	rtCreated, err := global.RedisClient.Set(global.RedisDataShare+":"+"auth:"+td.RefreshUuid, certKey, time.Second*time.Duration(refrushTokenExpire)).Result()

	if err != nil {
		return err
	}
	if atCreated == "0" || rtCreated == "0" {
		return errors.New("no record inserted")
	}

	return nil
}

//Check the metadata saved
func FetchAuth(tokenUuid string) (string, error) {
	userid, err := global.RedisClient.Get(global.RedisDataShare+":"+"auth:"+tokenUuid).Result()
	if err != nil {
		return "", err
	}
	return userid, nil
}

//Once a user row in the token table
func DeleteTokens(authD *model.AccessDetails) error {
	//get the refresh uuid
	refreshUuid := fmt.Sprintf("%s++%s", authD.TokenUuid, authD.AppId)
	//delete access token
	deletedAt, err := global.RedisClient.Del(global.RedisDataShare+":"+"auth:"+authD.TokenUuid).Result()
	if err != nil {
		return err
	}
	//delete refresh token
	deletedRt, err := global.RedisClient.Del(global.RedisDataShare+":"+"auth:"+refreshUuid).Result()
	if err != nil {
		return err
	}
	//When the record is deleted, the return value is 1
	if deletedAt != 1 || deletedRt != 1 {
		return errors.New("something went wrong")
	}
	return nil
}

func DeleteRefresh(refreshUuid string) error {
	//delete refresh token
	deleted, err := global.RedisClient.Del(global.RedisDataShare+":"+"auth:"+refreshUuid).Result()
	if err != nil || deleted == 0 {
		return err
	}
	return nil
}

func DeleteTokenByUserNameAndType(appId string,appSecret string) {
	sliceCmd := global.RedisClient.Keys(global.RedisDataShare+":"+"auth:"+"uuid_*")
	if sliceCmd == nil {
		return
	}
	val := sliceCmd.Val()
	for i:=0;i<len(val);i++ {
		res,_:= global.RedisClient.Get(val[i]).Result()
		var uuidVal model.UuidValue
		if err := json.Unmarshal([]byte(res),&uuidVal);err ==nil {
			if appId==uuidVal.AppId && appSecret==uuidVal.AppSecret{
				//删除记录
				global.RedisClient.Del(val[i]).Result()
			}
		}
	}
}
//
func LoadConnectInfo()([]model.DbConnInfo) {

	conn_array := make([]model.DbConnInfo,0)
	conn_list := global.RedisClient.LRange ("database",0,1000).Val()
	for i:=0;i<len(conn_list);i++{
		fmt.Println(conn_list[i])
		var conn_info model.DbConnInfo
		if err := json.Unmarshal([]byte(conn_list[i]),&conn_info);err ==nil {
			conn_array = append(conn_array,conn_info)
		}else{
			global.SystemLogger.Log(logrus.ErrorLevel,"load connection config failed,"+err.Error())
		}
	}
	return conn_array
}
//加载数据缓存参数
func LoadDataCacheList()([]model.DataCacheOfRedis){
	data_cache_list := make([]model.DataCacheOfRedis,0)
	cache_list := global.RedisClient.LRange ("datacache",0,1000).Val()
	for i:=0;i<len(cache_list);i++{
		var item_info model.DataCacheOfRedis
		if err := json.Unmarshal([]byte(cache_list[i]),&item_info);err ==nil {
			data_cache_list = append(data_cache_list,item_info)
		}else{
			global.SystemLogger.Log(logrus.ErrorLevel,"load data cache failed,"+err.Error())
		}
	}
	return data_cache_list
}

//获取接口调用次数
func GetApiCallCount(accessId string)(int){
	key := global.RedisDataShare +":"+"dayLimit"+":"+"dayLimit_"+accessId
	exist := global.RedisClient.Exists(key).Val()
	if exist == 0 {
		return 0
	}
	ret := global.RedisClient.Get(key).Val()
	cnt,_ := strconv.Atoi(ret)
	return cnt
}
//自增接口调用次数
func IncApiCallCount(accessId string)(error){
	key := global.RedisDataShare +":"+"dayLimit"+":"+"dayLimit_"+accessId
	count := GetApiCallCount(accessId)

	var year,month,day,hour,minute,second int
	currentTime := time.Now().Format("2006-01-02 15:04:05")
	_,_= fmt.Sscanf(currentTime,"%4d-%2d-%2d %2d:%2d:%2d",&year,&month,&day,&hour,&minute,&second)
	hh := 23-hour
	mm := 59-minute
	ss := 59 - second

	insert, err := global.RedisClient.Set(key, count+1, time.Second*time.Duration(hh*3600 + mm*60 + ss)).Result()
	if err != nil {
		return err
	}
	if insert == "0" {
		return errors.New("no record inserted")
	}

	return nil
}
