<?php

namespace Heanup\Frame\Package\Cache;

/**
 * 使用Redis做缓存
 */
class Redis extends \Heanup\Frame\Package\Cache
{
    const CONFIG_CLASS = 'Redis\\Core';
    const PREFIX = '';
    const EXPIRE = 0; // 3 天

    /**
     * 单个读取
     * @param $id
     * @return array
     */
    public static function get($id)
    {
        $key = self::getKey($id);
        try {
            $result = self::getConnection()->get($key);
        } catch (\Exception $ex) {
            $result = null;
        }
        return $result;
    }

    /**
     * 批量读取，如果没有数据，则对应的value为空
     * @param array $idList
     * @return array
     */
    public static function getBatch(Array $idList)
    {
        $keyList = array();
        foreach ($idList as $id) {
            $keyList[$id] = self::getKey($id);
        }
        try {
            $result = self::getConnection()->mget($keyList);
        } catch (\Exception $ex) {
            $result = null;
        }
        $data = array();
        if ($result) {
            $i = 0;
            foreach ($keyList as $k => $v) {
                $data[$k] = $result[$i];
                $i++;
            }
        }
        unset($result);
        unset($idList);
        unset($keyList);
        return $data;
    }

    /**
     * @param $id
     * @param int $data
     * @return bool
     */
    public static function set($id, $data)
    {
        if (is_array($data)) {
            $data = serialize($data);
        }
        $key = self::getKey($id);
        $class = get_called_class();
        try {
            if ($class::EXPIRE) {
                $result = self::getConnection(true)->setex($key, $class::EXPIRE, $data);
            } else {
                $result = self::getConnection(true)->set($key, $data);
            }
        } catch (\Exception $ex) {
            $result = false;
        }
        return $result;
    }

    /**
     * 批量设置
     * @param array $data
     * @return bool
     */
    public static function setBatch($data)
    {
        $dataList = array();
        foreach ($data as $k => $v) {
            $k = self::getKey($k);
            $v = is_array($v) ? serialize($v) : $v;
            $dataList[$k] = $v;
        }
        $class = get_called_class();
        try {
            $result = self::getConnection(true)->mset($dataList);
            // 设置过期时间
            if ($class::EXPIRE) {
                foreach ($dataList as $k => $v) {
                    self::getConnection()->expire($k, $class::EXPIRE);
                }
            }
        } catch (\Exception $ex) {
            $result = false;
        }
        unset($data);
        unset($dataList);
        return $result;
    }

    /**
     * 加1
     * @param $id
     * @param int $value
     * @return int
     */
    public static function increase($id, $value = 1)
    {
        $key = self::getKey($id);
        $value = abs($value);
        try {
            $result = self::getConnection(true)->incr($key, $value);
        } catch (\Exception $ex) {
            $result = false;
        }
        return $result;
    }

    /**
     * @param $id
     * @param int $value
     * @return int
     */
    public static function decrease($id, $value = 1)
    {
        $key = self::getKey($id);
        $value = abs($value);
        try {
            $result = self::getConnection(true)->decr($key, $value);
        } catch (\Exception $ex) {
            $result = false;
        }
        return $result;
    }

    /**
     * 删除
     * @param $id
     * @return bool
     */
    public static function delete($id)
    {
        $key = self::getKey($id);
        try {
            $result = self::getConnection(true)->delete($key);
        } catch (\Exception $ex) {
            $result = false;
        }
        return $result;
    }

    /**
     * 获取连接池
     * @param bool $isMaster
     * @return \Redis
     */
    protected static function getConnection($isMaster = false)
    {
        $class = get_called_class();
        $configClass = $class::CONFIG_CLASS;
        $redis = new \Heanup\Frame\Library\Redis($configClass);
        $connection = $redis->getConnection($isMaster);
        return $connection;
    }

}