package redis

import (
	"context"
	"gitee.com/xlizy/common-go/utils/zlog"
	"github.com/go-redis/redis/v8"
	"strconv"
	"time"
)

type RootConfig struct {
	Config redisConfig `yaml:"redis"`
}

type redisConfig struct {
	Addr     string `yaml:"addr"`
	Password string `yaml:"password"`
	DB       int    `yaml:"db"`
}

var _client *redis.Client

func NewConfig() *RootConfig {
	return &RootConfig{}
}

func InitRedis(rc *RootConfig) {
	// 初始化一个新的redis client
	_client = redis.NewClient(&redis.Options{
		Addr:     rc.Config.Addr,     // redis地址
		Password: rc.Config.Password, // redis没密码,没有设置,则留空
		DB:       rc.Config.DB,       // 使用默认数据库
	})
}

func Cli() *redis.Client {
	return _client
}

func RateLimit(ctx context.Context, window, maxCnt int, key string) bool {
	isExits := _client.Exists(ctx, "EXISTS", key).Val()
	timeStamp := time.Now().Unix()
	if isExits == 0 {
		_client.LPush(ctx, key, timeStamp)
		_client.Expire(ctx, key, time.Duration(window)*time.Second)
		zlog.Info("限流结果:允许放行")
		return true
	}
	lens := _client.LLen(ctx, key).Val()
	end := 0
	list := _client.LRange(ctx, key, 0, lens).Val()
	for i := int(lens - 1); i >= 0; i-- {
		str := list[i]
		oldStamp, _ := strconv.ParseInt(str, 10, 64)
		if timeStamp-oldStamp < int64(window) {
			end = i
			break
		}
	}

	_client.LTrim(ctx, key, 0, int64(end))

	if end+1 < maxCnt {
		_client.LPush(ctx, key, timeStamp)
		_client.Expire(ctx, key, time.Duration(window)*time.Second)
		zlog.Info("限流结果:允许放行")
		return true
	}
	zlog.Info("限流结果:禁止操作")
	return false
}