<?php

/**
 * Service.php
 */

namespace Server\Model;

use Framework\Define\ErrorDefine;
use Framework\Define\IControllerDefine;
use Framework\Log\LogMark;
use Framework\MVC\ControllerBase;
use Framework\Protobuf\InternalPacket;
use Framework\Protobuf\ServerRegister;
use Framework\DB\Handler\CommonDBHandler;
use Game\Config\GameConfig;
use Game\Constant\DBTableDefine;

class Service
{
    use CommonDBHandler;

    /**
     * @var IControllerDefine $controllerDefine 控制器字典
     */
    private IControllerDefine $controllerDefine;

    public string $serverID = "";
    public int    $createTime = 0;
    public int    $type = 0;
    public int    $status = 0;
    public string $explain = "";
    public $clientData = [];

    public function init(string $serverID, int $createTime, int $type = 0, int $status = 0, string $explain = "")
    {
        $this->serverID = $serverID;
        $this->createTime = $createTime;
        $this->type = $type;
        $this->status = $status;
        $this->explain = $explain;
    }

    /**
     * 模块初始化控制器字典
     * @param IControllerDefine $define 控制器字典
     */
    public function setControllerDefine(IControllerDefine $define) {
        $this->controllerDefine = $define;
    }

    public function run(): int
    {
        $this->getRDBData();
        if(empty($this->clientData)) {
            return ErrorDefine::SUCCESS;
        }

        $resMsg = base64_decode($this->clientData[1]);
        $message = new InternalPacket();
        $message->mergeFromString($resMsg);
        $packetID = $message->getPacketId();
        $sendTime = $message->getSendTime();
        $playerID = $message->getPlayerId();
        $sendServer = $message->getSendServer();
        $data = $message->getPacketData();

        $controller_name = $this->controllerDefine->getControllerName($packetID);
        if ($controller_name == "") {
            LogMark::getInstance()->markError(
                ErrorDefine::PACKET_ID_ERROR,
                "[service] create controller fail",
                array("packetId" => $packetID)
            );
            return ErrorDefine::PACKET_ID_ERROR;
        }
        /**
         * @var ControllerBase $controller
         */
        $controller = new $controller_name();
        $controller->init($playerID);
        $controller->setSendServer($sendServer);

        $str = base64_decode($data);
        LogMark::getInstance()->markInfo(
            '[service] get data :',
            [$sendTime, $sendServer, $str]
        );
        if(ErrorDefine::SUCCESS != $controller->parsing($str, $packetID)) {
            LogMark::getInstance()->markInfo(
                '[service] parse data error!',
                [$sendTime, $sendServer, $str]
            );
            return ErrorDefine::ERROR_INTERNAL;
        }
        if(ErrorDefine::SUCCESS != $controller->run()) {
            LogMark::getInstance()->markInfo(
                '[service] controller run error!',
                [$sendTime, $sendServer, $str]
            );
            return ErrorDefine::ERROR_INTERNAL;
        }
        return ErrorDefine::SUCCESS;
    }

    public function getRDBData():bool {
        if(!$this->searchBLPopQueue(DBTableDefine::TABLE_SERVICE_PACK, GameConfig::getInstance()->GAME_SERVICE_ID(), 0
            , $this->clientData)){
            return false;
        }
        if(empty($this->clientData)) {
            return true;
        }
        return true;
    }

    public function register(): bool {
        $msg = new ServerRegister();
        $msg->setServerId($this->serverID);
        $msg->setCreateTime($this->createTime);
        $msg->setType($this->type);
        $msg->setStatus($this->status);
        $msg->setExplain($this->explain);
//         protobuf 转json
        $data = $msg->serializeToJsonString();
        if(!$this->saveServiceInfo(DBTableDefine::TABLE_SERVICE_REGISTER, $this->serverID, $data)) {
            return false;
        }
        return true;
    }
}
