<?php
/**
 * Created by PhpStorm.
 * User: phperstar
 * Date: 2019/9/1
 * Time: 2:12 PM
 */
namespace JinDouYun\Model;

use Mall\Framework\Core\Config;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Factory;

class Middleware
{

    static private $instance;

    private $resourceConfig;
    private $Swoole_Client;

    public function __construct($serviceName)
    {
        $this->resourceConfig = Config::getInstance()->get('dataResources');
        if (!empty($this->resourceConfig)) {
            $this->Swoole_Client = Factory::swoole($this->resourceConfig[$serviceName]);
        }
    }

    /**
     * 单例模式
     *
     * @param string $serviceName 服务名称
     *
     * @return object
     *
     * @throws \Exception
     */
    static public function getInstance($serviceName)
    {
        /*$serviceNameIndex = md5($serviceName);
        if (!isset(self::$instance[$serviceNameIndex])) {
            self::$instance[$serviceNameIndex] = new self($serviceName);
        }

        if (is_null(self::$instance[$serviceNameIndex]->resourceConfig)) {
            throw new \Exception('instance resourceConfig is null');
        }
        return self::$instance[$serviceNameIndex];*/
        return new self($serviceName);
    }

    /**
     * 发送swoole请求 目前统一封装为json消息体传输
     *
     * @param string $controller 控制器
     * @param string $action 方法
     * @param array $params 需要的参数
     *
     * @return mixed
     */
    public function sendSwoole($controller, $action, array $params = [])
    {
        //请求串号
        $serid = self::getRequestId();

        $msg = $this->structureMsg($controller, $action, $params, $serid);
        $result = $this->Swoole_Client->sendMsg($msg, $serid);

        if (!empty($result)) {
            return $result;
        } else {
            //todo 日志记录返回为空时得请求消息体

            return [
                'state' => false,
                'data' => 'swoole未返回消息',
                'errorcode' => ErrorCode::$swooleRecvError
            ];
        }
    }

    /**
     * 生成请求串号
     * @return int
     */
    static function getRequestId()
    {
        $us = strstr(microtime(), ' ', true);
        return intval(strval($us * 1000 * 1000) . rand(100, 999));
    }

    /**
     * 构造发送消息体
     *
     * @param string $controller 控制器
     * @param string $action 方法
     * @param array $params 需要的参数
     * @param int   $serid  请求串号
     *
     * @return string
     */
    private function structureMsg($controller, $action, $params = [], $serid,  $uid = 0)
    {
        $data = json_encode([
            'contorller' => ucfirst($controller),
            'action' => $action,
            'params' => $params
        ], JSON_UNESCAPED_UNICODE);
        return pack('NNN', strlen($data), $uid, $serid) . $data;
    }
}
