package cache

import (
	"context"
	"errors"
	"time"

	"github.com/redis/go-redis/v9"
	"github.com/rs/zerolog/log"
)

type RedisCache struct {
	name string
	ctx  context.Context
	rdb  *redis.Client
}

func (r *RedisCache) Set(key string, value []byte, ttl time.Duration) error {
	log.Trace().Str("key", r.name+"::"+key).Int("len(value)", len(value)).Bytes("value", value).Msg("Set in Redis.")
	return r.rdb.Set(r.ctx, r.name+"::"+key, value, ttl).Err()
}

func (r *RedisCache) Get(key string) ([]byte, bool) {
	val, err := r.rdb.Get(r.ctx, r.name+"::"+key).Bytes()
	if err != nil {
		if !errors.Is(err, redis.Nil) {
			log.Error().Err(err).Str("key", r.name+"::"+key).Msg("Couldn't request key from cache.")
		} else {
			log.Trace().Str("key", r.name+"::"+key).Msg("Get from Redis, doesn't exist.")
		}
		return nil, false
	} else {
		log.Trace().Str("key", r.name+"::"+key).Int("len(value)", len(val)).Msg("Get from Redis.")
		return val, true
	}
}

func (r *RedisCache) Remove(key string) {
	err := r.rdb.Del(r.ctx, r.name+"::"+key).Err()
	if err != nil {
		log.Error().Err(err).Str("key", r.name+"::"+key).Msg("Couldn't delete key from cache.")
	}
}

func NewRedisCache(name string, opts *redis.Options) ICache {
	return &RedisCache{
		name,
		context.Background(),
		redis.NewClient(opts),
	}
}