<?php

namespace pictpostpersonal;

use Exception;
use pictpostpersonal\Request;
use pictpostpersonal\Result;
use pictpostpersonal\Router;
use pictpostpersonal\Logger;
use pictpostpersonal\ResponseEmitter;
use pictpostpersonal\service\ThemeService;
use pictpostpersonal\Utility;

require_once 'autoload.php';

class main
{

    private $db;

    function __construct(\PDO $db)
    {
        $this->db = $db;
    }

    function run(): void
    {
        //セッションスタート
        Utility::SessionStart();

        //設定読み取り
        $setting = new model\Setting($this->db);

        //ロガー生成
        if (!file_exists(dirname(SYSTEM_LOG))) {
            mkdir(dirname(SYSTEM_LOG));
        }
        $log = new Logger(SYSTEM_LOG);

        //ログレベル設定
        $log_level = $setting->getValue('log_level', Logger::LOG_LEVEL_WARN);
        $log->setLogLevel($log_level);

        //環境系初期化
        //　SITE_URL, BASE_URL定数が定義される
        Environment::InitEnvironment($setting);

        //リクエスト構成
        $request = new Request();

        //認証システム構築
        $auth = new Authentification($request);

        //テーマ処理
        $cache_dir = './env/template_cache';

        if ($auth->isLogin() && $request->getArgs("theme_preview", "")) {
            //ログイン済みかつテーマ指定がある場合書き換え
            $setting->setValue("theme",  $request->getArgs("theme_preview", ""));
            $_SESSION["preview_theme"] = $request->getArgs("theme_preview", "");
            $cache_dir = './env/template_cache/preview';
            array_map('unlink', glob('./env/template_cache/preview/*.cache'));
        } else if ($auth->isLogin() && isset($_SESSION["preview_theme"])) {
            $setting->setValue("theme",  $_SESSION["preview_theme"]);
            $cache_dir = './env/template_cache/preview';
        }

        $theme = new ThemeService($this->db, $setting, $cache_dir);

        // Contextオブジェクトを生成
        $context = new Context($this->db, $setting, $theme, $auth, $log);

        //ルーティング設定
        $router = new Router($request, '../public/', new ResponseEmitter(), $context);


        //インデックス
        $router->any('(/|/index.php|/index.html)', function ($e) {
            if ($e->getArgs('q', '')) {
                //rewriteが使用できない環境用動作 (https://example.com/?q=123)
                $result = new Result(0, '', '', ['middleware\EntryMiddleware:siteEntryCheck', 'middleware\NSFWMiddleware:siteNSFWCheck', 'page\ArticlePage:showArticleByQ']);
                return $result;
            } else {
                $result = new Result(0, '', '', ['middleware\EntryMiddleware:siteEntryCheck', 'middleware\NSFWMiddleware:siteNSFWCheck', 'page\IndexPage:show']);
                return $result;
            }
        });


        //CSRFトークン更新
        $router->get('/api/v2/refreshtoken', ['middleware\AuthMiddleware:adminCheckApi', 'middleware\CSRFMiddleware:refreshToken']);

        //API群
        //記事API
        $router->delete('/api/v2/articles/{id}', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi', 'api\ArticleApi:delete']); //記事削除
        $router->post('/api/v2/articles/{id}', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi',  'api\ArticleApi:update']);  //記事更新
        $router->patch('/api/v2/articles/{id}', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi',  'api\ArticleApi:update']);  //記事更新
        $router->post('/api/v2/articles', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi', 'api\ArticleApi:create']);        //記事投稿

        $router->delete('/api/v2/articles/{id}/media/{image_id}', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi', 'api\ArticleApi:deleteMedia']); //画像削除
        $router->post('/api/v2/articles/{id}/media/{image_id}',   ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi', 'api\ArticleApi:updateMedia']); //画像更新
        $router->patch('/api/v2/articles/{id}/media/{image_id}',   ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi', 'api\ArticleApi:updateMedia']); //画像更新
        $router->post('/api/v2/articles/{id}/media',              ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi', 'api\ArticleApi:uploadMedia']); //画像投稿

        $router->get('/api/v2/articles/{id}/like',  ['api\ArticleApi:getLikeCount']); //LIKE取得・一般からも可
        $router->post('/api/v2/articles/{id}/like', ['middleware\CSRFMiddleware:CSRFCheck',  'api\ArticleApi:addLikeCount']); //LIKE増加・一般からも可
        $router->get('/api/v2/articles/weeklikes', ['middleware\AuthMiddleware:adminCheckApi', 'api\ArticleApi:getWeekLikes']);

        //メッセージAPI
        $router->post('/api/v2/messages', ['middleware\CSRFMiddleware:CSRFCheck', 'api\MessageApi:create']); //メッセージ作成・一般からも可
        $router->delete('/api/v2/messages/{id}', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi', 'api\MessageApi:delete']); //メッセージ削除
        $router->patch('/api/v2/messages/{id}', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi', 'api\MessageApi:update']);  //メッセージ更新
        $router->post('/api/v2/messages/{id}/read', ['middleware\AuthMiddleware:adminCheckApi', 'api\MessageApi:read']); //メッセージ既読処理
        $router->delete('/api/v2/messages/{id}/read', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheckApi', 'api\MessageApi:unread']); //メッセージ既読解除

        //メールAPI
        $router->post('/api/v2/mail', ['middleware\CSRFMiddleware:CSRFCheck', 'api\MailApi:create']); //メール作成・一般からも可

        //アクティビティAPI
        $router->get('/api/v2/activity/get', ['middleware\AuthMiddleware:adminCheckApi', 'api\ActivityApi:get']); //アクティビティ一覧取得
        $router->get('/api/v2/activity/get/{format}', ['middleware\AuthMiddleware:adminCheckApi', 'api\ActivityApi:get']); //指定のアクティビティ取得
        $router->post('/api/v2/activity/readed', ['middleware\AuthMiddleware:adminCheckApi', 'api\ActivityApi:markAllAsRead']); //アクティビティ既読設定

        //ナビゲートAPI
        $router->get('/api/v2/navigate', ['api\NavigateApi:get']);  //ナビゲート履歴取得
        $router->post('/api/v2/navigate', ['api\NavigateApi:write']);   //ナビゲート履歴設定
        $router->delete('/api/v2/navigate', ['api\NavigateApi:delete']);    //ナビゲート履歴削除
        $router->delete('/api/v2/navigate/all', ['api\NavigateApi:deleteAll']); //ナビゲート履歴全削除

        //ログイン処理
        $router->get('/login', 'page\LoginPage:show');   //ログイン画面表示
        $router->post('/login', ['middleware\CSRFMiddleware:CSRFCheck', 'page\LoginPage:login']); //ログイン処理
        $router->any('/logout', 'page\LoginPage:logout'); //ログアウト処理

        //設定 関係
        $router->get('/setting/admintool', ['middleware\AuthMiddleware:adminCheck', 'page\AdminTool:show']);
        $router->get('/setting/backup', ['middleware\AuthMiddleware:adminCheck', 'page\AdminTool:backup']);
        $router->get('/setting/csvexport', ['middleware\AuthMiddleware:adminCheck', 'page\AdminTool:csvexport']);
        $router->get('/setting/update', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheck', 'page\AdminTool:update']);
        $router->any('/setting/external_token_console', ['middleware\AuthMiddleware:adminCheck', 'page\AdminTool:external_token_console']);
        $router->any('/setting/portal_console', ['middleware\AuthMiddleware:adminCheck', 'page\AdminTool:portal_console']);

        $router->post('/setting', ['middleware\CSRFMiddleware:CSRFCheck', 'middleware\AuthMiddleware:adminCheck', 'page\SettingPage:save']);
        $router->get('/setting', ['middleware\AuthMiddleware:adminCheck', 'page\SettingPage:show']);
        $router->get('/setting.php', ['middleware\AuthMiddleware:adminCheck', 'page\SettingPage:show']); //互換性

        $router->get('/setting/css', ['middleware\AuthMiddleware:adminCheck', 'page\AdminTool:showUserCss']);
        $router->post('/setting/css', ['middleware\AuthMiddleware:adminCheck', 'middleware\CSRFMiddleware:CSRFCheck', 'page\AdminTool:saveUserCss']);

        //コンソール
        $router->any('/console/messages', ['middleware\AuthMiddleware:adminCheck', 'page\ConsolePage:showMessageList']);
        $router->any('/console/articles', ['middleware\AuthMiddleware:adminCheck', 'page\ConsolePage:showArticleList']);
        $router->any('/console.php', ['middleware\AuthMiddleware:adminCheck', 'page\ConsolePage:showArticleList']); //互換性
        $router->any('/console', ['middleware\AuthMiddleware:adminCheck', 'page\ConsolePage2:showConsole']);

        //TODO:管理系処理の追加
        //TODO:SNS連携
        //TODO:ポータル連携
        //TODO:バージョンアップ
        //TODO:テンプレート管理

        //記事 投稿/編集/削除
        $router->get('/edit/{id}', ['middleware\AuthMiddleware:adminCheck', 'page\EditPage:edit']);
        $router->get('/edit', ['middleware\AuthMiddleware:adminCheck', 'page\EditPage:create']);
        $router->get('/edit.php', ['middleware\AuthMiddleware:adminCheck', 'page\EditPage:add']); //互換性

        //記事表示 関係

        $router->any('/log/{id}/{page}', ['middleware\EntryMiddleware:siteEntryCheck', 'middleware\NSFWMiddleware:siteNSFWCheck', 'page\ArticlePage:showArticleById']);
        $router->any('/log/{id}',  ['middleware\EntryMiddleware:siteEntryCheck', 'middleware\NSFWMiddleware:siteNSFWCheck', 'page\ArticlePage:showArticleById']);
        $router->any('/log', function (Request $e) {
            Result::redirect(BASE_URL);
        });
        $router->any('/view.php',  ['middleware\EntryMiddleware:siteEntryCheck', 'middleware\NSFWMiddleware:siteNSFWCheck', 'page\ArticlePage:showArticleById']); //互換性

        //検索
        $router->any('/search', ['page\SearchPage:search']); // ~/sesarch?q=word&page=2
        $router->any('/list.php', ['page\SearchPage:search']); //互換性

        //テーマ系ファイル
        $router->any('/theme/resource', ['page\ThemePage:getResourceFile']);
        $router->any('/theme', ['page\ThemePage:getFile']);

        //メディア直アクセス
        $router->any('/media/{id}/{sort}', 'page\MediaPage:getFile');
        $router->any('/media/thumb/{id}/{sort}', 'page\MediaPage:getThumbnail');
        $router->any('/media/thumb_l/{id}/{sort}', 'page\MediaPage:getLargeThumbnail');

        //日付形式での記事表示
        $router->any('/log/{year}/{month}/{day}/{index}', ['middleware\EntryMiddleware:siteEntryCheck', 'middleware\NSFWMiddleware:siteNSFWCheck', 'page\ArticlePage:showArticleByDate']);
        $router->any('/log/{year}/{month}/{day}', ['middleware\EntryMiddleware:siteEntryCheck', 'middleware\NSFWMiddleware:siteNSFWCheck', 'page\ArticlePage:showArticleByDate']);

        //リライト確認用
        $router->any('/mod_rewrite_check', function ($e) {
            echo 'mod_rewrite is enabled';
            return null;
        });

        //デフォルトルート 固定記事URLとして処理する
        $router->defaultRoute(['middleware\EntryMiddleware:siteEntryCheck', 'middleware\NSFWMiddleware:siteNSFWCheck', 'page\ArticlePage:showArticleByURL']);

        //404ページ
        $router->error404(function (Request $e) {
            $url = htmlspecialchars($e->url);
            return new Result(404, "404! {$url}");
        });

        //リクエストログ記録
        $log->log($_SERVER['REQUEST_URI'], Logger::LOG_LEVEL_NORMAL);
        $log->log(print_r($_GET, true),  Logger::LOG_LEVEL_NORMAL);
        $log->log(print_r($_POST, true), Logger::LOG_LEVEL_NORMAL);

        $router->run();
    }
}
