<?php

try {
    require_once(dirname(__FILE__) . '/application.php');
    require_once(dirname(__FILE__) . '/setup.php');
    require_once(dirname(__FILE__) . '/lib/schema.php');
    require_once(dirname(__FILE__) . '/lib/fix.php');

    class Surfacer_FixBlogAlign extends Surfacer
    {
        public function buildSurface(&$Tpl, $root)
        {
            $DB = DB::singleton(dsn());
            $SQL = SQL::newSelect('blog');
            $SQL->setSelect('blog_id');
            $SQL->setGroup('blog_id');
            $SQL->setHaving(SQL::newOpr(SQL::newFunction('blog_id', 'count'), 2, '>='));
            $SQL->setLimit(1);

            if (!!($bid = intval($DB->query($SQL->get(dsn()), 'one')))) {
                $SQL = SQL::newSelect('blog');
                $SQL->addWhereOpr('blog_id', $bid);
                $i = 1;
                foreach ($DB->query($SQL->get(dsn()), 'all') as $row) {
                    $Tpl->add(['status:touch#', 'delete', $root] . $row['blog_status']);
                    $Tpl->add(['indexing:touch#', 'delete', $root] . $row['blog_indexing']);
                    $Tpl->add(
                        ['blog:loop', 'delete', $root],
                        [
                            'i' => $i++,
                            'bid' => $row['blog_id'],
                            'code' => $row['blog_code'],
                            'status' => $row['blog_status'],
                            'parent' => $row['blog_parent'],
                            'sort' => $row['blog_sort'],
                            'left' => $row['blog_left'],
                            'right' => $row['blog_right'],
                            'name' => $row['blog_name'],
                            'domain' => $row['blog_domain'],
                            'indexing' => $row['blog_indexing'],
                        ]
                    );
                }
            } else {
                $Tpl->add(['align', $root]);
            }
        }

        public function validate()
        {

            if ($this->Post->get('action') === 'delete' && $this->Post->isNull('i')) {
                $this->Error['bid_input'] = true;
            }

            $this->detectStep();
        }

        public function business()
        {
            $args = [];
            if ($this->Post->get('action') == 'delete') {
                $args['selected'] = intval($this->Post->get('i'));
                $args['count'] = count($_POST['count']);

                $Fix = new Fix_BlogDelete($args);

                if (!$Fix->execute($this->Post)) {
                    $this->Error['execute'] = true;
                }
            } elseif ($this->Post->get('action') == 'align') {
                $Fix = new Fix_BlogAlign($args);

                if (!$Fix->execute()) {
                    $this->Error['execute'] = true;
                }
            }

            $this->detectStep();
        }
    }

    class Surfacer_FixCategoryAlign extends Surfacer
    {
        public function buildSurface(&$Tpl, $root)
        {
            /*
            * list blog
            */
            $DB = DB::singleton(dsn());
            $SQL = SQL::newSelect('blog');
            $all = $DB->query($SQL->get(dsn()), 'all');

            foreach ($all as $row) {
                $vars = [
                    'bid' => $row['blog_id'],
                    'name' => $row['blog_name'],
                    'code' => $row['blog_code'],
                    'parent' => $row['blog_parent'],
                ];
                $Tpl->add(['blog:loop', $root], $vars);
            }
        }

        public function validate()
        {

            if ($this->Post->isNull('bid')) {
                $this->Error['bid_input'] = true;
            }

            $this->detectStep();
        }

        public function business()
        {
            $args = ['bid' => $this->Post->get('bid')];

            $Fix = new Fix_CategoryAlign($args);

            if (!$Fix->execute()) {
                $this->Error['execute'] = true;
            }

            $this->detectStep();
        }
    }


    class Surfacer_FixCommentAlign extends Surfacer
    {
        public function buildSurface(&$Tpl, $root)
        {
            /*
            * list blog
            */
            $DB = DB::singleton(dsn());
            $SQL = SQL::newSelect('blog');
            $all = $DB->query($SQL->get(dsn()), 'all');

            foreach ($all as $row) {
                $vars = [
                    'bid' => $row['blog_id'],
                    'name' => $row['blog_name'],
                    'code' => $row['blog_code'],
                    'parent' => $row['blog_parent'],
                ];
                $Tpl->add(['blog:loop', $root], $vars);
            }
        }

        public function validate()
        {

            if ($this->Post->isNull('bid')) {
                $this->Error['bid_input'] = true;
            }

            $this->detectStep();
        }

        public function business()
        {
            $args = ['bid' => $this->Post->get('bid')];

            $Fix = new Fix_CommentAlign($args);

            if (!$Fix->execute()) {
                $this->Error['execute'] = true;
            }

            $this->detectStep();
        }
    }

    class Surfacer_FixDomain extends Surfacer
    {
        public function buildSurface(&$Tpl, $root)
        {
        }

        public function validate()
        {
            if ($this->Post->isNull('domain')) {
                $this->Error['domain_input'] = true;
            } elseif (!preg_match(REGEX_VALID_DOMAIN, $this->Post->get('domain'))) {
                $this->Error['domain_invalid'] = true;
            }

            if (!SetupCommon::checkPermission(PATH_CONFIG, '666')) {
                $this->Error['config_permission'] = true;
            }

            $this->detectStep();
        }

        public function business()
        {
            $DB = DB::singleton(dsn());

            $domain = $this->Post->get('domain');
            $all_blog = $this->Post->get('all_blog');

            $SQL = SQL::newUpdate('blog');
            $SQL->addUpdate('blog_domain', $domain);
            if ($all_blog !== 'on') {
                $SQL->addWhereOpr('blog_id', 1);
            }
            $DB->query($SQL->get(dsn()), 'exec');

            if (!SetupCommon::rebuildConfig(['DOMAIN' => $domain])) {
                $this->Error['rewrite_config'] = true;
            }

            $this->detectStep();
        }
    }

    class Surfacer_FixIndex extends Surfacer
    {
        public function buildSurface(&$Tpl, $root)
        {
        }

        public function validate()
        {
            if (!SetupCommon::checkAlterPerm()) {
                $this->Error['alter_privilege'] = true;
            }

            $this->detectStep();
        }

        public function business()
        {
            $Schema = new Schema(dsn(), DB_NAME, DB_PREFIX);
            $Schema->defSetYaml('schema');
            $defs = Schema::listUp($Schema->define);
            foreach ($defs as $def) {
                $Schema->clearIndex($def);
            }
            $newIndex = $Schema->defLoadYaml('index');
            foreach ($newIndex as $table => $index) {
                $Schema->makeIndex($table, $index);
            }
            $this->detectStep();
        }
    }

    class Surfacer_FixAccess extends Surfacer
    {
        public function buildSurface(&$Tpl, $root)
        {
            /*
            * list blog
            */
            $DB = DB::singleton(dsn());
            $SQL = SQL::newSelect('blog');
            $all = $DB->query($SQL->get(dsn()), 'all');

            foreach ($all as $row) {
                $vars = [
                    'bid' => $row['blog_id'],
                    'name' => $row['blog_name'],
                    'code' => $row['blog_code'],
                    'parent' => $row['blog_parent'],
                ];
                $Tpl->add(['blog:loop', $root], $vars);
            }
        }

        public function validate()
        {
            if ($this->Post->isNull('bid')) {
                $this->Error['bid_input'] = true;
            }

            $this->detectStep();
        }

        public function business()
        {
            $bid = $this->Post->get('bid');
            $DB = DB::singleton(dsn());
            $delete_target = [
                'login_white_hosts',
                'login_black_hosts',
                'signin_white_hosts',
                'signin_black_hosts',
                'basic_auth_user',
                'basic_auth_pass',
                'basic_auth_skip_hosts',
            ];

            $SQL = SQL::newDelete('config');
            $SQL->addWhereOpr('config_blog_id', $bid);
            $SQL->addWhereIn('config_key', $delete_target);
            $DB->query($SQL->get(dsn()), 'exec');

            Cache::flush('config');

            $this->detectStep();
        }
    }

    class Surfacer_FixFieldSearch extends Surfacer
    {
        public function buildSurface(&$Tpl, $root)
        {
        }

        public function validate()
        {
            $this->detectStep();
        }

        public function business()
        {
            $DB = DB::singleton(dsn());

            $SQL = SQL::newUpdate('field');
            $SQL->addUpdate('field_search', 'on');
            $SQL->addWhereOpr('field_key', '%@%', 'NOT LIKE');
            $DB->query($SQL->get(dsn()), 'exec');

            $this->detectStep();
        }
    }

    /**
     * Detect Switching Call Class
     */

    switch ($_GET['c']) {
        case 'blog-align':
            $tplPath = dirname(__FILE__) . "/tpl/fix/blog-align.html";
            new Surfacer_FixBlogAlign($tplPath);
            break;
        case 'category-align':
            $tplPath = dirname(__FILE__) . "/tpl/fix/category-align.html";
            new Surfacer_FixCategoryAlign($tplPath);
            break;
        case 'comment-align':
            $tplPath = dirname(__FILE__) . "/tpl/fix/comment-align.html";
            new Surfacer_FixCommentAlign($tplPath);
            break;
        case 'domain':
            $tplPath = dirname(__FILE__) . "/tpl/fix/domain.html";
            new Surfacer_FixDomain($tplPath);
            break;
        case 'index':
            $tplPath = dirname(__FILE__) . "/tpl/fix/index.html";
            new Surfacer_FixIndex($tplPath);
            break;
        case 'field-search':
            $tplPath = dirname(__FILE__) . "/tpl/fix/field-search.html";
            new Surfacer_FixFieldSearch($tplPath);
            break;
        case 'access':
            $tplPath = dirname(__FILE__) . "/tpl/fix/access.html";
            new Surfacer_FixAccess($tplPath);
            break;
        default:
            header('Content-type: text/html; charset=UTF-8');
            die('<p>不正な命令です</p>');
            break;
    }

    App::checkException();
} catch (Exception $e) {
    App::showError($e);
}
