<?php


namespace app\task\controller;


use think\Console;
use think\console\Input;
use think\console\Output;
use think\Controller;
use think\Exception;
use think\facade\Config;
use think\facade\Env;
use think\Db;
use think\facade\Log;

define('MYSQL_MIN_VERSION', '5.5.3');

class InstallController extends Controller
{
    /**
     * @param $mode string|array
     */
    public function index($sql = '', $mode = '')
    {
        $runtimepath = Env::get('runtime_path');
        if (file_exists($runtimepath . 'install.lock')) {
            header('Location: /');
            exit;
        }

        if ($this->request->isPost()) {
            set_time_limit(0);
            @ini_set('max_execution_time', 0);

            $db = $this->request->post('db');
            if (!empty($db) && !empty($db['hostname'])) {
                $dbconfig = config('database.');
                $needupdate = false;

                foreach ($db as $k => $v) {
                    if (isset($dbconfig[$k]) && $v != $dbconfig[$k]) {
                        $needupdate = true;
                        break;
                    }
                }
                if ($needupdate) {
                    $config = env('config_path') . 'database.php';
                    if (!is_writable($config)) {
                        $this->error('数据库配置文件不可写,请修改权限或手动配置');
                    }
                    $content = file_get_contents($config);
                    $content = preg_replace_callback('/\'([\w\d]+)\'(\s*)=>(\s*)\'[^\']+\'/', function ($matches) use ($db, &$dbconfig) {
                        if (isset($db[$matches[1]])) {
                            $dbconfig[$matches['1']] = $db[$matches['1']];
                            return "'{$matches['1']}'{$matches['2']}=>{$matches['3']}'{$db[$matches['1']]}'";
                        }
                        return $matches[0];
                    }, $content);

                    file_put_contents($config, $content);
                    Config::set($dbconfig, 'database');
                }
            }
            $console = Console::init(false);
            $output = new Output('buffer');
            $args = ['install'];
            if (!empty($sql)) {
                $args[] = '--sql';
                $args[] = $sql;
            }
            if (!empty($mode)) {
                $args[] = '--module';
                $args[] = is_array($mode) ? implode(',', $mode) : $mode;
            }
            if ($this->request->has('admin', 'post')) {
                $args[] = '--username';
                $args[] = $this->request->post('admin');
            }
            if ($this->request->has('password', 'post')) {
                $args[] = '--password';
                $args[] = $this->request->post('password');
            }
            $input = new Input($args);

            $console->doRun($input, $output);

            $message = $output->fetch();
            if (strpos($message, 'success') !== false) {
                $this->success($message);
            } else {
                $this->error($message);
            }
        }

        $envs = [];
        $mysqlenv = ['title' => 'Mysql', 'require' => MYSQL_MIN_VERSION, 'current' => '', 'pass' => null];
        $dbcfg = config('database.');
        try {
            if (!empty($dbcfg['hostname'])) {
                $version = Db::connect($dbcfg)->query('select version()');
                $mysqlenv['current'] = $version[0]['version()'];
                if ($mysqlenv['current'] && version_compare($mysqlenv['require'], $mysqlenv['current'], '<=')) {
                    $mysqlenv['pass'] = true;
                } else {
                    $mysqlenv['pass'] = false;
                }
            }
        } catch (Exception $e) {
        }
        $envs[] = $mysqlenv;

        $phpenv = ['title' => 'PHP', 'require' => '7.1.3', 'current' => PHP_VERSION, 'pass' => false];
        if (version_compare($phpenv['require'], $phpenv['current'], '<=')) {
            $phpenv['pass'] = true;
        }
        $envs[] = $phpenv;

        $phpsqlenv = ['title' => 'PHP-数据库', 'require' => 'Mysqli/PDO', 'current' => '', 'pass' => false];
        $exists = [];
        if (function_exists('mysqli_connect')) {
            $exists[] = 'Mysqli';
            $phpsqlenv['pass'] = true;
        }
        if (class_exists('PDO')) {
            if (defined('PDO_MYSQL')) {
                $exists[] = 'PDO-Mysql';
                $phpsqlenv['pass'] = true;
            } else {
                $exists[] = 'PDO';
            }
        }
        $phpsqlenv['current'] = implode(' & ', $exists);
        $envs[] = $phpsqlenv;

        $phpgdenv = ['title' => 'PHP-gd', 'require' => '*', 'current' => '', 'pass' => false];
        if (function_exists('gd_info')) {
            $gdinfo = gd_info();
            $phpgdenv['current'] = $gdinfo['GD Version'];
            $phpgdenv['pass'] = true;
        }
        $envs[] = $phpgdenv;

        $phpmbenv = ['title' => 'PHP-mbstring', 'require' => '*', 'current' => '', 'pass' => false];
        if (function_exists('mb_strlen')) {
            $phpmbenv['pass'] = true;
        }
        $envs[] = $phpmbenv;

        $phpsslenv = ['title' => 'PHP-OpenSSL', 'require' => '*', 'current' => '', 'pass' => false];
        if (function_exists('openssl_encrypt')) {
            $phpsslenv['pass'] = true;
        }
        $envs[] = $phpsslenv;

        $phpcurlenv = ['title' => 'PHP-curl', 'require' => '*', 'current' => '', 'pass' => false];
        if (function_exists('curl_version')) {
            $version = curl_version();
            $phpcurlenv['current'] = $version['version'];
            $phpcurlenv['pass'] = true;
        }
        $envs[] = $phpcurlenv;

        $pass = true;
        foreach ($envs as $item) {
            if ($item['pass'] === false) {
                $pass = false;
                break;
            }
        }
        $this->assign('envs', $envs);
        $this->assign('pass', $pass);
        return $this->fetch();
    }

    public function connectdb($db)
    {
        if (empty($db['hostname'])) {
            $this->error('主机名称未填写');
        }
        $db['type'] = 'mysql';
        try {
            $version = Db::connect($db)->query('select version()');
            $versionstr = $version[0]['version()'];
        } catch (\Throwable $e) {
            $message = $e->getMessage();
            Log::error($message);
            $this->error('数据库连接失败');
        }

        if ($versionstr && version_compare($versionstr, MYSQL_MIN_VERSION, '>=')) {
            $this->success('数据库连接成功');
        }
        $this->error('数据库版本最低' . MYSQL_MIN_VERSION . ',当前' . $versionstr);
    }
}
