<?php

namespace xmvc\core;

use xmvc\MVC;
use xmvc\Dump;
use xmvc\Queue;
use xmvc\Viewer;
use xmvc\Encoder;
use xmvc\Session;
use xmvc\core\Power;

class Cmd
{
    /** 隐藏方法退出core登录 /xmvc/core/cmd-logout , 隐藏方法 logout() 通过 xmvc\core\power的验证方法实现 */

    /**
     * index
     */
    public function index()
    {
        require(DIR_MVC . '/core/cmd/' . __FUNCTION__ . '.php');
        exit();
    }
    /**
     * 元数据
     * @menu
     */
    public function metadata()
    {
        require(DIR_MVC . '/core/cmd/' . __FUNCTION__ . '.php');
        exit();
    }

    /**
     * PHPINFO
     * @menu
     */
    public function phpinfo()
    {
        phpinfo();
        exit();
    }

    /**
     * 站点首次运行, 初始化一些内容(例缓存目录)
     * @menu
     */
    public function runFirst()
    {
        $indexFile = ROOT . '/index.php';
        $phpCode = file_get_contents($indexFile);
        //将index配置文件中的 FIRST_RUN 修改为 true
        $phpCode = preg_replace('/define\(([\s]+)?[\'|\"]FIRST_RUN[^;]+\;/is', "define('FIRST_RUN', true);", $phpCode);
        if ($phpCode) {
            file_put_contents_lock($indexFile, $phpCode);
        }
        echo '<script>fetch("' . HTTP_HOST . '")</script>';
        MVC::alert('执行完成', '首次初始化运行');
        exit();
    }

    /**
     * 显示 常量, 配置, $_SESSION, $_SERVER
     * @menu
     */
    public function cfg()
    {
        echo '<body style="padding:1em">';

        echo '<h1>常量</h1>';
        dump(get_defined_constants(true)['user']);

        echo '<h1>配置数组</h1>';
        //echo '<p>不含数据库配置</p>';
        $db = new \xmvc\DB();
        dump(MVC::$cfg);

        echo '<h1>_SESSION</h1>';
        if (isset($_SESSION)) {
            dump('注意存在 $_SESSION', $_SESSION);
        }
        dump(Session::getAll());

        echo '<h1>_SERVER</h1>';
        dump($_SERVER);
        exit();
    }

    /**
     * 配置文件
     * @menu
     */
    public function cfgUI()
    {
        require(DIR_MVC . '/core/cmd/' . __FUNCTION__ . '.php');
        exit();
    }

    /**
     * 生成所有视图缓存, 会先清空模板缓存目录
     * @menu
     */
    public function createAllTplCacheFile()
    {
        Viewer::createAllCacheFile();
        MVC::alert('生成完成', '生成所有视图缓存');
        exit();
    }

    /**
     * 更新静态文件版本号 - 使用当前 time()
     * @menu
     */
    public function updateSVER()
    {
        $indexFile = ROOT . '/index.php';
        $phpCode = file_get_contents($indexFile);
        $phpCode = preg_replace('/define\(([\s]+)?[\'|\"]SVER[^;]+\;/is', "define('SVER', " . time() . ");", $phpCode);
        if ($phpCode) {
            file_put_contents_lock($indexFile, $phpCode);
        }
        echo '<script>fetch("' . HTTP_HOST . '")</script>';
        MVC::alert('执行完成', '更新静态文件版本号');
        exit();
    }

    /**
     * 创建一个新的类, 使用 /xmvc/core/codeTpl/class.tpl.php 样板
     *
     * @param [string] $param 目标文件目录,base64编码
     */
    public function newClass(string $param)
    {
        $tmp = base64_decode($param);
        list($filename, $function) = explode('|', $tmp);
        if (file_exists($filename)) {
            error($filename . ' 类文件已存在');
        }
        $site = getSiteNameByDir($filename);
        $site = $site ? $site : '';
        $class = filenameNotExt($filename);
        $namespace = str_replace('/', '\\', dirname(substr($filename, strlen(ROOT))));
        $tplContents = file_get_contents(DIR_MVC . '/xmvc/core/codeTpl/class.tpl.php');
        $tplContents = qgprintf($tplContents, [
            'site' => $site,
            'namespace' => $namespace,
            'class' => $class,
            'function' => $function,
        ]);
        file_put_contents($filename, $tplContents);
        chmod($filename, 0777);
        MVC::alert('已生成类文件: ' . $filename, '新的类');
        exit();
    }

    /**
     * 创建一个新的 action类, 使用 xmvc/core/codeTpl/action.tpl.php 样板
     *
     * @param [string] $param 目标文件目录,base64编码
     */
    public function newAction(string $newClassName, string $newClassFunction, string $newClassFile)
    {
        if (file_exists($newClassFile)) {
            MVC::warning($newClassFile . ' 控制器文件已存在', '存在');
            exit();
        }
        $site = getSiteNameByDir($newClassFile);
        $site = $site ? $site : '';
        $action = filenameNotExt($newClassFile);
        $namespace = substr($newClassName, 0, strlen($newClassName) - strlen($action) - 1);
        $namespace = str_replace('/', '\\', $namespace);
        $tplContents = file_get_contents(DIR_MVC . '/core/codeTpl/action.tpl.php');
        $tplContents = qgprintf($tplContents, [
            'site' => $site,
            'action' => $action,
            'namespace' => $namespace,
            'function' => $newClassFunction,
        ]);
        mkdirs(dirname($newClassFile));
        file_put_contents($newClassFile, $tplContents);
        chmod($newClassFile, 0777);
        MVC::alert('已生成控制器文件: ' . $newClassFile, '创建');
        exit();
    }

    /**
     * 创建一个新的模板文件, 使用 xmvc/core/codeTpl/tpl.tpl.php 样板
     *
     * @param [string] $param 目标文件目录,base64编码
     */
    public function newTpl(string $newClassFile)
    {
        if (file_exists($newClassFile)) {
            error($newClassFile . ' 模板文件已存在');
        }
        $site = getSiteNameByDir($newClassFile);
        $site = $site ? $site . '/' : '';
        $tplContents = file_get_contents(DIR_MVC . '/core/codeTpl/tpl.tpl.php');
        $tplContents = qgprintf($tplContents, ['site' => $site]);
        mkdirs(dirname($newClassFile));
        file_put_contents($newClassFile, $tplContents);
        chmod($newClassFile, 0777);
        MVC::alert('已生成模板文件: ' . $newClassFile, '新模板');
        exit();
    }

    /**
     * 显示 PHP 文件代码
     *
     * @param string $filename
     * @param int $line 加亮第几行
     */
    public function showPhpCode($filename, $line, $begin = 0, $end = 0, bool $return = false)
    {
        require(DIR_MVC . '/core/cmd/' . __FUNCTION__ . '.php');
        return R($code_string);
    }

    /**
     * APCu UI
     * @menu
     */
    public function apcu()
    {
        require(DIR_MVC . '/core/cmd/' . __FUNCTION__ . '.php');
        exit();
    }

    /**
     * Redis UI
     * @menu
     */
    public function redis()
    {
        require(DIR_MVC . '/core/cmd/' . __FUNCTION__ . '.php');
        exit;
    }

    /**
     * Beanstalkd 状态信息
     * @menu
     */
    public function beanstalkdStatus()
    {
        $queue = Queue::create('Beanstalk');
        $data = $queue->status();
        dump($data['tubes']);
        dump($data['status']);
        exit;
    }

    /**
     * 创建控制台密码 Hash 值, 默认 admin/Yi&parts.2008 哈希 b2add2944893de6e06a2a9fc7318a3a1
     * @param string $user 用户名
     * @param string $pass 密码
     * @menu
     */
    public function corePass($user, $pass)
    {
        $pass .= '.'; // 未尾加点号防当前面的.后面内容当成扩展名
        MVC::alert((new Power())->passwordForWWWAuth($user, $pass), $user . ' 的控制台密码如下');
        exit();
    }

    public function showErrorLogFile(string $date)
    {
        $filename = DIR_LOG . '/error/' . substr($date, 0, 4) . '/' . $date . '.log';
        $this->showLogFile($filename, 1024);
        exit();
    }

    public function showLogFile(string $filename, $maxline = 0)
    {
        require(DIR_MVC . '/core/cmd/' . __FUNCTION__ . '.php');
        exit();
    }

    public function clearErrorLogFile(string $date)
    {
        $filename = DIR_LOG . '/error/' . substr($date, 0, 4) . '/' . $date . '.log';
        if (is_file($filename)) {
            $backupFilename = $filename . '.backup';
            if (!is_file($backupFilename)) {
                copy($filename, $backupFilename);
                unlink($filename);
            } else {
                MVC::echo('<div class="box-alert"><h1>EXISTS ' . relDir($backupFilename) . '</h1><p>已存在备份文件, 如要继续请手动处理.</p></div>');
            }
        } else {
            MVC::echo('<div class="box-alert"><h1>NOT FOUND ' . relDir($filename) . '</h1><p>日志文件不存在</p></div>');
        }
        exit();
    }
}
