package redis

import (
	"errors"
	"log"
	"strings"
	"time"

	red "github.com/gomodule/redigo/redis"
)

var redisPool map[string]*red.Pool

//初始化
func InitRedis(addrs string) {
	redisPool = map[string]*red.Pool{}
	addr := strings.Split(addrs, ",")
	for _, v := range addr {
		saddr := strings.Split(v, "=")
		redisPool[saddr[0]] = &red.Pool{
			MaxIdle:     256,
			MaxActive:   0,
			IdleTimeout: time.Duration(120),
			Dial: func() (red.Conn, error) {
				return red.Dial(
					"tcp",
					saddr[1],
					red.DialReadTimeout(time.Duration(2000)*time.Millisecond),
					red.DialWriteTimeout(time.Duration(2000)*time.Millisecond),
					red.DialConnectTimeout(time.Duration(2000)*time.Millisecond),
					red.DialDatabase(0),
				)
			},
		}
	}
}

//存储
func PutRedis(code string, db int, key, val interface{}, timeout int) bool {
	b := false
	var err error
	con := redisPool[code].Get()
	if err = con.Err(); err != nil {
		log.Println("redisutil-conn Error", err)
		return b
	}
	defer con.Close()
	_, err = con.Do("select", db)
	if err != nil {
		log.Println("redisutil-select Error", err)
		return b
	}
	if timeout <= 0 {
		_, err = con.Do("SET", key, val)
	} else {
		_, err = con.Do("SET", key, val, "EX", timeout)
	}
	if err != nil {
		log.Println("redisutil-set Error", err)
		return b
	} else {
		b = true
	}
	return b
}

//获取字符串
func GetRedisStr(code string, db int, key interface{}) (string, error) {
	res, err := GetNewInterface(code, db, key)
	if err != nil {
		return "", err
	} else {
		if res == nil {
			return "", nil
		} else {
			if bt, ok := res.([]byte); ok {
				return string(bt), nil
			} else { //转化出错
				return "", errors.New("Error Converting Data")
			}
		}
	}
}

func GetNewInterface(code string, db int, key interface{}) (res interface{}, err error) {
	con := redisPool[code].Get()
	if err = con.Err(); err != nil {
		return nil, err
	}
	defer con.Close()
	_, err = con.Do("select", db)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return con.Do("GET", key)
}

//判断是否存在
func ExistRedis(code string, db int, key interface{}, args ...interface{}) (bool, error) {
	con := redisPool[code].Get()
	if err := con.Err(); err != nil {
		log.Println("redis exist error:", err)
		return false, err
	}
	defer con.Close()
	_, err := con.Do("select", db)
	if err != nil {
		log.Println("redis select error:", err)
		return false, err
	}
	parmas := make([]interface{}, 0)
	parmas = append(parmas, key)
	if len(args) > 0 {
		for _, v := range args {
			parmas = append(parmas, v)
		}
	}
	repl, err := con.Do("exists", parmas...)
	ret, _ := red.Int(repl, err)
	return ret == 1, err
}
