package redis

import (
	"fmt"
	"time"

	"git.rosy.net.cn/baseapi/utils"
	"github.com/go-redis/redis"
)

type Cacher struct {
	client *redis.Client
}

func New(host string, port int, password string) *Cacher {
	if port == 0 {
		port = 6379
	}
	return &Cacher{
		client: redis.NewClient(&redis.Options{
			Addr:     fmt.Sprintf("%s:%d", host, port),
			Password: password,
		},
		),
	}
}

func (c *Cacher) FlushKeys(prefix string) (err error) {
	if prefix == "" {
		return c.client.FlushAll().Err()
	}
	keys, err := c.Keys(prefix)
	if err == nil {
		for _, key := range keys {
			if err = c.Del(key); err != nil {
				break
			}
		}
	}
	return err
}

func (c *Cacher) Set(key string, value interface{}, expiration time.Duration) error {
	strValue := string(utils.MustMarshal(value))
	return c.client.Set(key, strValue, expiration).Err()
}

func (c *Cacher) Del(key string) error {
	return c.client.Del(key).Err()
}

func (c *Cacher) Get(key string) interface{} {
	result, err := c.client.Get(key).Result()
	if err == nil {
		var retVal interface{}
		if err = utils.UnmarshalUseNumber([]byte(result), &retVal); err == nil {
			return retVal
		}
	}
	return nil
}

func (c *Cacher) GetAs(key string, ptr interface{}) error {
	result, err := c.client.Get(key).Result()
	if err == nil {
		if err = utils.UnmarshalUseNumber([]byte(result), ptr); err == nil {
			return nil
		}
	}
	return err
}

func (c *Cacher) Keys(prefix string) ([]string, error) {
	return c.client.Keys(prefix + "*").Result()
}
