<?php

namespace Heanup\Frame;

class Session
{

    protected static $expire = ADMIN_TOKEN_EXPIRED;

    /**
     * 设置超时时间, 初始化 cookie等
     *
     * @param int $expire
     * @throws \Exception
     */
    public static function start($expire = 1800)
    {
        if (is_numeric($expire)) {
            self::$expire = $expire;
        }
        self::getSessionId();
    }

    /**
     * 设置会话信息
     *
     * @param string $key
     * @param string $data
     * @param null $user_id
     * @return bool
     */
    public static function set($key, $data, $user_id = null)
    {
        $sessionId = self::getSessionId($user_id);
        try {
            $redis = self::getConnection(true);
            $isExisted = $redis->exists($sessionId);
            $result = $redis->hSet($sessionId, $key, $data);
            // if (!$isExisted) {
            $redis->expire($sessionId, self::$expire);
            // }
        } catch (\Exception $ex) {
            Logger::debug($ex, 'session.set');
            $result = false;
        }
        return $result;
    }

    /**
     * 读取会话信息
     *
     * @param $key
     * @param null $user_id
     * @return mixed
     */
    public static function get($key, $user_id = null)
    {

        $sessionId = self::getSessionId($user_id);
        try {
            $redis = self::getConnection();
            $result = $redis->hGet($sessionId, $key);
            $redis->expire($sessionId, self::$expire);
        } catch (\Exception $ex) {
            Logger::debug($ex, 'session.get');
            $result = null;
        }
        return $result;
    }

    /**
     * 获取所有的会话信息
     *
     * @param null $user_id
     * @return array
     */
    public static function getAll($user_id = null)
    {
        $sessionId = self::getSessionId($user_id);
        try {
            $result = self::getConnection()->hGetAll($sessionId);
        } catch (\Exception $ex) {
            Logger::debug($ex, 'session.get_all');
            $result = array();
        }
        return $result;
    }

    /**
     * 删除会话
     *
     * @param null $user_id
     * @return bool
     */
    public static function destroy($user_id = null)
    {
        $sessionId = self::getSessionId($user_id);
        try {
            $result = self::getConnection(true)->delete($sessionId);
            $_COOKIE[$sessionId] = null;
        } catch (\Exception $ex) {
            Logger::debug($ex, 'session.destroy');
            $result = false;
        }
        return $result;
    }

    /**
     * 获取会话ID
     *
     * @param null $user_id
     * @return string
     * @throws \Exception
     */
    public static function getSessionId($user_id = null)
    {
        if ($user_id) {
            $sessionId = md5($user_id);
        } else {
            $host = $_SERVER['HTTP_HOST'];
            $key = 'sid:' . crc32($host);
            if (!$_COOKIE[$key]) {
                $sessionId = md5(microtime() . rand() . uniqid());
                $result = setcookie($key, $sessionId, time() + self::$expire * 10, '/', $host, null, true);
                if (!$result) {
                    throw new \Exception('set cookie failed', 9000);
                }
            } else {
                $sessionId = $_COOKIE[$key];
            }
        }
        return $sessionId;
    }

    /**
     *
     * @param bool $isMaster
     * @return \Redis
     * @internal param $ $isMaster*            $isMaster
     */
    protected static function getConnection($isMaster = false)
    {
        $configClass = 'Redis\Session';
        $redis = new \Heanup\Frame\Library\Redis($configClass);
        $connection = $redis->getConnection($isMaster);
        return $connection;
    }
}