<?php

namespace App\Tool;

use \Symfony\Component\HttpFoundation\Response;

/**
 * 常用函数
 */
trait ToolFunc
{

    /**
     * 检测当前异常是否属于自定义异常
     * @param Exception $exception 抛出的异常
     * @return Array $arr 当前异常的类名和自定义异常的数组
     */
    public static function handlerException($exception)
    {
        $class_name = self::getClassName($exception);
        $files = self::getExceptionFileName();
        $bool = in_array($class_name, $files);
        if ($bool) {
            return [$class_name,$files];
        } else {
            return false;
        }
    }
    /**
     * getClassName 获取当前触发异常的异常类名
     * @param Exception $exception 异常对象
     * @return String $str 异常类名字
     */
    public static function getClassName($exception)
    {
        return substr(strrchr(get_class($exception), '\\'), 1);
    }
    /**
     * getExceptionFileName获取app/Exceptions下面所有的异常类文件并按照文件名排序
     * @return Array $files 文件名数组
     */
    public static function getExceptionFileName()
    {
        $files = array_map(function ($v) {
            return basename($v, '.php');
        }, glob(app_path('Exceptions').'/*Exception.php'));
        return $files;
    }
    /**
     * 控制器抛出异常
     */
    public static function exceptionHandler($e, ...$ext)
    {
        $error_message = $e->getMessage();
        $result = self::handlerException($e);
        if ($result) {
            $message = json_decode($error_message, true);
            if ($ext[0] == 'throw') {
                $exception = '\\App\\Exceptions\\'.$result[0];
                throw new $exception(...$message);
            } else {
                return $message;
            }
        } else {
            if ($ext[0] == 'throw') {
                array_shift($ext);
                throw new \App\Exceptions\ControllerException(...$ext);
            } else {
                return $error_message;
            }
        }
    }

//    function handler_drive($callback)
//    {
//        try {
//            if (!is_callable($callback)) {
//                throw new \Exception('callback is not callable');
//            }
//            $result = $callback();
//        } catch (\Exception $e) {
//            $error_message = $e->getMessage();
//            $result = \App\Tool\ToolFunc::handlerException($e);
//            if ($result) {
//                $message = json_decode($error_message, true);
//                $exception = '\\App\\Exceptions\\' . $result[0];
//                throw new $exception(...$message);
//            }
//
//            throw new \App\Exceptions\ControllerException($error_message);
//        }
//        return $result;
//    }


    /**
     * 处理put传过来的值
     * @param str
     * @return array data
     */
    public static function getPutValueHandle($request)
    {

        $str = $request->getContent();
        $r = explode(PHP_EOL, $str);
        $request_temp = [];

        foreach ($r as $k => $v) {
            $v = trim($v);
            if ($v == '' || ( strpos($v, '---') )  === 0) {
                unset($r[$k]);
            }
            if (preg_match('/"(.*)"/', $v, $name)) {
                $request_temp[$name[1]] = str_replace(["\r\n","\r","\n"], '', $r[$k+2]);
            }
        }
        $request->replace($request_temp);
    }


    /**
     * 节点排序
     */
    public static function sortPermission($temp, $temp1)
    {
        foreach ($temp as $key => $value) {
            foreach ($temp1 as $k => $v) {
                if ($value['id'] == $k) {
                    array_unshift($v, $value);
                    unset($temp[$key]);
                    array_splice($temp, $key, 0, $v);
                    unset($temp1[$k]);
                    return [$temp,$temp1];
                }
            }
        }
    }


    /**
     * 添加分页浏览ID
     * @param obj $obj  数据集
     * @param int $page 当前页码
     * @return $obj
     */
    public static function addPageNum($obj, $page = 1)
    {
        foreach ($obj as $k => $v) {
            if ($page && $page > 1) {
                $v->num = 10 * ($page - 1) + $k + 1;
            } else {
                $v->num = $k+1;
            }
        }
        return $obj;
    }


    /**
     * 转换一个int为byte大小
     * @param $val 需要转换的字符串
     * @return **MB
     */
    public static function calc($size, $digits = 2)
    {
        if (!$size) {
            return 0;
        }
        if (is_numeric($size)) {
            $unit= array('','K','M','G','T','P');
            $base= 1024;
            $i = floor(log($size, $base));
            $n = count($unit);
            if ($i >= $n) {
                $i=$n-1;
            }
            return round($size/pow($base, $i), $digits).' '.$unit[$i] . 'B';
        } else {
            return $size;
        }
    }

    /**
     * 房间是否失效
     */
    public static function checkRoomFail($room_id)
    {
        $r = \App\Model\RoomModel::where('id', $room_id)->first();
        if ($r === null) {
            throw new \App\Exceptions\ControllerException(1019, '房间不存在');
        }
        $r = $r->toArray();
        if ($r['status'] == 0) {
            throw new \App\Exceptions\ControllerException(1020, '房间还未编辑,不能进行该操作');
        }
        $time = strtotime($r['end_time']);
        if (time() >= ($time + 86400)) {
            throw new \App\Exceptions\ControllerException(1021, ',不能进行该操作');
        }
    }

    /**
     * 对称加密
     * @param string $string
     * @param string $skey
     * @return mixed
     */
    public static function encode($string = "")
    {
        $strArr = str_split(base64_encode($string));
        $strCount = count($strArr);
        foreach (str_split('20190115.offcn.com') as $key => $value) {
            $key < $strCount && $strArr[$key] .= $value;
        }
        return str_replace(array('=', '+', '/'), array('O0O0O', 'o000o', 'oo00o'), join($strArr));
    }

    /**
     * 判断是否有base64加密
     * @param $str
     * @return bool
     */
    public static function is_base64($str)
    {
        if(mb_strlen($str) >= 8) {
            return $str == base64_encode(base64_decode($str)) ? true : false;
        }

    }

    /**
     * sign签名
     */
    public static function get_sign($data)
    {
        //对数组的值按key排序
        ksort($data);
        // 生成url的形式
        $params = http_build_query($data);
        // 生成sign
        $sign = md5($params . '69b72c8$M^O(F`F8CdN5f13517');
        return $sign;
    }

    public function validatorBoolean($value)
    {
        return preg_match('/^[01]{1}$/', $value);
    }

}
