<?php

namespace loyalsoft;

/**
 * Description of SelfChecker
 * 框架的自我检查工具
 * @author gwang
 */
class SelfChecker {

    public static function CheckAll() {
//        self:: checkkPHPVersion();
//        self::checkModules();
        self::CheckDNS();
        self::CheckNetRead();
        self::CheckConfig();
    }

    /**
     * 检查模块是否加载
     * @param string[] $arr 要检查的模块名称
     */
    public static function checkModules($arr = array()) {
        $default = array(#                                                      # 必备基础模块
            "curl",
            "mbstring",
            "openssl",
            "pdo_mysql",
            "sockets",
            "zlib",
        );
        $r_modules = array_merge($default, $arr);                               # 合并指定模块
        $diff = array_diff($r_modules, get_loaded_extensions());                # 判断缺失模块
        if (count($diff)) {                                                     # 确实缺失模块
            die("require modules: " . implode(' ,', $diff));                    # 直接结束运行
        }
    }

    /**
     * 检查PHP版本
     * @param string $ver 最低版本字符串类似于7.3.5
     */
    public static function checkkPHPVersion($ver = null) {
        $default_ver = "5.4.16";
        $r_ver = isset($ver) ? $ver : $default_ver;
        if (version_compare(PHP_VERSION, $r_ver, '<')) {
            die('<font color="red">This code request at least PHP version ' . $r_ver #
                    . ', Current version: ' . PHP_VERSION . ".</font><br/>" . PHP_EOL);
        }
    }

    /**
     * 检查配置文件
     */
    public static function CheckConfig() {
        echoLine("检查配置:");
        echoLine("GameOnline: " . GAME_ONLINE);
        echoLine("MySQL Connect Settings; " . var_export(config::Inst()->paydb, true));
        self::TestMysql_RW();
        echoLine("NoSql(Redis) Connect Settings: " . var_export(config::Inst()->nosql, true));
        self::TestNoSQL_RW();
        echoLine("Upload path Settings: " . "本框架暂未涉及.");
    }

    /**
     * DNS检查
     * @param type $url
     */
    public static function CheckDNS($url = 'qq.com') {
        echoLine("DNS check $url is " . (checkdnsrr($url, "A") ? "ok!" : "failed!"));
    }

    public static function CheckNetRead($url = 'qq.com') {
        $ret = HttpUtil::makeRequest($url, array());
        if ($ret["result"]) {
            echoLine("Request to $url ok!");
        } else {
            echoLine("Net Request Failed!:" . $ret['msg']);
        }
    }

// <editor-fold defaultstate="collapsed" desc="  内部函数  ">

    /**
     * 测试NoSql连接,以及读写性能
     */
    private static function TestNoSQL_RW() {
        $key = "test-" . TimeUtil::tsYmdHis();
        echoLine("Redis Server is running: " . gMem()->ping());
        echoLine("Redis Write($key, 'Hello world!'):" . gMem()->set($key, "Hello world!"));
        echoLine("Redis Read($key): " . gMem()->get($key));
        echo("Profile Redis set/get: ");
        RenderTime::Test(function ()use($key) {
            gMem()->set($key, "Hello world!");
            gMem()->get($key);
        }, 100);
    }

    /**
     * 测试MySQL连接,以及读写性能
     */
    private static function TestMysql_RW() {
        $tableName = "test-" . date('Ymd');
        echoLine("Connection is " . (daoInst()->Ping() ? "ok!" : "gone!"));
        $bCretaTable = daoInst()->tableExist($tableName);
        if ($bCretaTable) {
            echoLine("Table $tableName is Existing.");
        } else {
            echoLine("Table $tableName is not Existing.");
            $sql = " CREATE TABLE if NOT exists `$tableName` (`row` INT(11) NOT NULL AUTO_INCREMENT COMMENT '自增行号',`msg` TEXT NULL DEFAULT NULL COMMENT '消息内容' COLLATE 'utf8_general_ci',	PRIMARY KEY (`row`) USING BTREE) COLLATE='utf8_general_ci' ENGINE=INNODB ; ";
            daoInst()->exec($sql);
            echoLine("create table $tableName " . (daoInst()->tableExist($tableName) ? "success!" : "failed!"));
        }

        $row = daoInst()->insert("`$tableName`")->data(array('msg' => 'Hello world!'))->exec();
        echoLine("Insert into `$tableName` " . ($row == 1 ? "ok!" : "failed!"));
        echo("Profile Insert: ");
        RenderTime::Test(function()use($tableName) {
            daoInst()->insert("`$tableName`")->data(array('msg' => 'Hello world!'))->exec();
        }, 100);
        $sql = "Drop Table `$tableName`;";
        daoInst()->exec($sql);
        echoLine("delete table $tableName " . (daoInst()->tableExist($tableName) ? "failed!" : "success!"));
    }

// </editor-fold>
}

SelfChecker::checkkPHPVersion();                                                # 检查PHP版本
SelfChecker::checkModules();                                                    # 检查PHP模块