<?php

/**
 * Load.php
 * 文件描述
 * Created On 2022/1/19
 * @author yuanb yuanbo0x@gmail.com
 */

namespace Tool\LoadScript;

use Exception;
use Framework\DB\DBContainer;
use Library\DB\IRedis;
use Game\Constant\DBTableDefine;

class Load
{
    use Log;

    private array $lua;

    private array $sha;

    public function __construct()
    {
        $this->sha = array();
        $this->lua = array();
    }

    public function main(): bool
    {
        DBContainer::getInstance()->init(new DBTableDefine());
        if ($this->loadLuaFile() == false) {
            return false;
        }
        foreach (DBTableDefine::DB_TYPE_LIST as $type) {
            $dbHandle = DBContainer::getInstance()->getRedisByConfig($type);
            if ($this->redisLoadScript($dbHandle) == false) {
                return false;
            }
        }
        if ($this->writeConfig() == false) {
            return false;
        }
        return true;
    }

    private function redisLoadScript(IRedis $redis): bool
    {
        foreach ($this->lua as $scriptName => $contents) {
            $sha = "";
            if (false == $redis->script($sha, array('load', $contents)) || $sha == false) {
                $log = "redis load script error:    ".$scriptName.":    " . $redis->getLastError();
                $this->addError($log);
                return false;
            }
            $this->sha[$scriptName] = $sha;
        }
        return true;
    }

    private function writeConfig(): bool
    {
        $shaStr = var_export($this->sha, true);
        $shaStr = str_replace(' ', '', $shaStr);
        $shaStr = str_replace('=>', ' => ', $shaStr);
        $shaStr = str_replace("\n", "\n        ", $shaStr);
        $shaStr = str_replace("    )", ")", $shaStr);
        $text = <<<data
        <?php
        
        namespace Game\Constant;
        
        class GameDBLogicDefine
        {
            public const LOGIC_LIST = $shaStr;
        }

        data;

        try {
            if (false == fopen(Config::SCRIPT_SHA, 'w+')) {
                $this->addError("open script sha error");
                return false;
            }
            if (file_put_contents(Config::SCRIPT_SHA, $text) == false) {
                $this->addError("write script sha error");
                return false;
            }
            return true;
        } catch (Exception $e) {
            $this->addError("write script sha Exception:" . $e->getMessage());
        }
        return false;
    }

    private function loadLuaFile(): bool
    {
        if (!is_dir(Config::SCRIPT_PATH)) {
            $this->addError("Script Dir Error " . Config::SCRIPT_PATH);
            return false;
        }
        $fileList = scandir(Config::SCRIPT_PATH);
        foreach ($fileList as $fileName) {
            $arr = explode('.', $fileName);
            if (count($arr) != 2 || $arr[1] != "lua") {
                continue;
            }
            $key = $arr[0];
            $contents = "";
            if (false == $this->readFile(Config::SCRIPT_PATH . $fileName, $contents)) {
                $this->addError("open file fail :" . Config::SCRIPT_PATH . $fileName);
                return false;
            }
            $this->lua[$key] = $contents;
        }
        return true;
    }

    private function readFile($path, &$contents): bool
    {
        $handle = fopen($path, 'r');
        if ($handle == false) {
            return false;
        }
        $contents = fread($handle, filesize($path));
        fclose($handle);
        return true;
    }
}
