<?php


namespace Framework\DB\Handler;


use Framework\DB\DBContainer;
use Framework\DB\DBManager;
use Framework\Lib\Utils;
use Game\Constant\DBTableDefine;
use Game\Constant\GameDBLogicDefine;
use Library\Common\Singletons;
use Library\DB\IRedis;

class PlayerDBPipe
{
    use Singletons;

    private int $playerId;

    private bool $inPipe = false;

    private array $cache = array();

    private $redisClient = null;

    private ?IRedis $redis;

    /// 管道开启
    /// 管道只能给玩家批量创建数据使用
    /// 管道期间，全局只能是这个玩家的数据表创建
    /// 全局禁止任何通过其他接口写入数据
    /// 全局禁止期间有额外的数据库操作
    public function start($playerId)
    {
        if ($this->inPipe) {
            return;
        }
        $this->inPipe = true;
        $this->playerId = $playerId;
        $dbKey = Utils::makeDBKey(DBTableDefine::TABLE_ACCOUNT, $playerId, 1);
        $this->cache = array($dbKey);
        $this->redis = DBContainer::getInstance()->getRedisByConfig(DBTableDefine::DB_TYPE_PLAYER);
        $this->redis->startPipe();
    }

    public function createTitle($table, $playerId, $titleId, $data, $score = 0): bool
    {
        if (!$this->inPipe) {
            return false;
        }
        if ($playerId !== $this->playerId) {
            return false;
        }
        $dbKey = Utils::makeDBKey($table, $playerId, $titleId);
        $param = array($dbKey, "$titleId", $score);
        foreach ($data as $k => $v) {
            array_push($param, $k);
            if ($k == "Id") {
                array_push($param, "$v");
            } else {
                array_push($param, $v);
            }
        }
        array_push($this->cache, json_encode($param));
        return true;
    }

    public function finish(): bool
    {
        if (!$this->inPipe) {
            return false;
        }
        $ret = "";

        if (false == $this->redis->pipeEvalSha(
                $ret,
                GameDBLogicDefine::LOGIC_LIST[DBTableDefine::DB_LOGIC_PIPE_PLAYER_CREATE_TITLE],
                $this->cache,
                1
            )) {
            return false;
        }
        $this->inPipe = false;
        $this->redis->finishPipe();
        return true;
    }
    
}