<?php

/**
 * 发送消息给客户端
 * Created On 2021/11/1
 * @author yuanb yuanbo0x@gmail.com
 */

namespace Framework\Network;

use Game\Constant\TestParams;
use Library\Common\Singletons;
use Library\Crypt;
use Framework\Log\LogMark;
use Framework\Protobuf\ClientError;
use Framework\Protobuf\WebRespondMessage;
use Framework\Protobuf\SinglePacket;
use Game\Logic\AccountLogic;
use Game\Protobuf\PacketId;
use Google\Protobuf\Internal\Message;

/**
 * 发送消息管理类
 */
class SendMessage
{
    use Singletons;
    use Crypt;
    use AccountLogic;

    /**
     * @var WebRespondMessage $respond_message 发送给客户端的响应消息
     */
    private WebRespondMessage $respond_message;

    /**
     * @var array $arr 包的队列，需要发给客户端的包都存入在这
     */
    private array $arr = [];

    /**
     * 初始化模块
     */
    public function init()
    {
        $this->respond_message = new WebRespondMessage();
        $this->lastPacketMessage = null;
    }

    /**
     * 设置index
     * @param int $index 包序列号
     */
    public function setIndex(int $index)
    {
        $this->respond_message->setIndex($index);
    }

    // 上次消息缓存
    private ?string $lastPacketMessage;

    public function setLastPacketMessage(string $packetMessage)
    {
        $this->lastPacketMessage = $packetMessage;
    }

    /**
     * 将包发送给客户端
     */
    public function respondClient()
    {
        if (is_null($this->lastPacketMessage)) {
            $this->respond_message->setPacketList($this->arr);
            $str = $this->respond_message->serializeToString();
            $data = $this->encrypt($str);
            // $data = base64_encode($data);
            //缓存消息
            $this->cachePacket(base64_encode($data));
            TestParams::$packetSize = strlen($data);
            echo $data;
        } else {
            LogMark::getInstance()->markDebug(
                "reconnect packet",
                array(
                    "index" => $this->respond_message->getIndex()
                )
            );
            echo base64_decode($this->lastPacketMessage);
        }
    }

    /**
     * 添加发送给客户端的消息包
     * @param int  $packetId 消息包id
     * @param Message $packet 消息包
     */
    public function sendClient(int $packetId, Message $packet)
    {
        //日志忽略消息列表
        $ignorePacketList = array(
            PacketId::GC_UpdateTime,     //普通心跳
        );
        if (!in_array($packetId, $ignorePacketList)) {
            $data = $this->dealJsonStr($packet->serializeToJsonString());
            LogMark::getInstance()->markDebug(
                "send packet to client",
                array(
                    "packetId" => $packetId,
                    "packet" => $data
                )
            );
        }
        $single_packet = new SinglePacket();
        $single_packet->setId($packetId);
        $packetStr = base64_encode($packet->serializeToString()) ;
        $single_packet->setData($packetStr);
        $this->arr[] = $single_packet;
    }

    public function dealJsonStr(string $data): string {
        return str_replace("\\", "", $data);
    }

    /**
     * @param int $errorId 错误id
     */
    public function sendErrorClient(int $errorId)
    {
        $packet = new ClientError();
        $packet->setErrorId($errorId);
        $this->sendClient(PacketId::Server_Error, $packet);
    }

    /**
     * 缓存包
     * @param string $msg
     */
    public function cachePacket(string $msg)
    {
        if ($msg == "") {
            return;
        }
        $index = $this->respond_message->getIndex();
        //缓存数据
        $this->savePacketCache($index, $msg);
    }
}
