<?php

use Acms\Services\Setup\SetupCommon;

define('REQUEST_TIME', time());
define('START_TIME', microtime(true));

$script_dir = dirname(dirname($_SERVER['SCRIPT_FILENAME'])) . '/';
$script_name = dirname(dirname($_SERVER['SCRIPT_NAME'])) . 'index.php';
$script_file_name = $script_dir . 'index.php';

require_once $script_dir . 'php/vendor/autoload.php';

if (preg_match('@(.*?)([^/]+)$@', $_SERVER['SCRIPT_FILENAME'], $match)) {
    $scriptDir = $match[1];
    if (file_exists($scriptDir . '.env')) {
        Dotenv\Dotenv::createImmutable($scriptDir)->load();
    }
}
function env($key, $default = '')
{
    return isset($_ENV[$key]) ? $_ENV[$key] : $default;
}

/**
 * config.server.php
 */
if (!is_file($script_dir . 'config.server.php')) {
    die('config.server.php is missing');
}

require_once $script_dir . 'config.server.php';
require_once $script_dir . PHP_DIR . 'config/app.php';
require_once $script_dir . PHP_DIR . 'config/polyfill.php';

setPath($script_file_name, $script_name);

/**
 * autoload
 */
spl_autoload_register('autoload');

/**
 * Application env（Use of undefined constant対策）
 */
if (!defined('BID')) {
    define('BID', 1);
}
if (!defined('DATE')) {
    define('DATE', null);
}
if (!defined('IS_DEVELOPMENT')) {
    define('IS_DEVELOPMENT', null);
}
if (!defined('SEARCH_ENGINE_KEYWORD')) {
    define('SEARCH_ENGINE_KEYWORD', null);
}
if (!defined('SUID')) {
    define('SUID', null);
}
if (!defined('SBID')) {
    define('SBID', null);
}
if (!defined('EID')) {
    define('EID', null);
}
if (!defined('CID')) {
    define('CID', null);
}
if (!defined('UID')) {
    define('UID', null);
}
if (!defined('VIEW')) {
    define('VIEW', null);
}
if (!defined('AID')) {
    define('AID', null);
}
if (!defined('SESSION_NEXT_ID')) {
    define('SESSION_NEXT_ID', null);
}
if (!defined('RBID')) {
    define('RBID', null);
}
if (!defined('SESSION_USE_COOKIE')) {
    define('SESSION_USE_COOKIE', null);
}
if (!defined('CMID')) {
    define('CMID', null);
}
if (!defined('UTID')) {
    define('UTID', null);
}
if (!defined('ACMS_SID')) {
    define('ACMS_SID', null);
}
if (!defined('RID')) {
    define('RID', null);
}
if (!defined('ADMIN')) {
    define('ADMIN', '');
}
if (!defined('ORDER')) {
    define('ORDER', '');
}
if (!defined('PAGE')) {
    define('PAGE', 1);
}
if (!defined('END')) {
    define('END', '');
}
if (!defined('START')) {
    define('START', '');
}
if (!defined('FIELD')) {
    define('FIELD', '');
}
if (!defined('TAG')) {
    define('TAG', '');
}
if (!defined('KEYWORD')) {
    define('KEYWORD', '');
}
if (!defined('RVID')) {
    define('RVID', null);
}
if (!defined('SYSTEM_GENERATED_DATETIME')) {
    define('SYSTEM_GENERATED_DATETIME', null);
}
if (!defined('IS_SETUP')) {
    define('IS_SETUP', true);
}

/**
 * application
 */
$config = appConfig();

$app = new Acms\Application();
$app->init($config['aliases'], $config['providers']);

/**
 * 例外ハンドラの集約
 *
 * setup の各エントリは従来、ファイル全体を try/catch で包んで App::showError に流していた。
 * ここで set_exception_handler を張り、未捕捉例外（loadLicense / 各コントローラ /
 * App::checkException）を一括で描画する。薄いエントリ（index / fix）は自前の try/catch を
 * 撤去してこのハンドラに委ねる。App::showError() は Throwable を直接受けるため、Error 系
 * （TypeError 等）も Exception へ包み直さず同じエラーページで処理できる。
 */
set_exception_handler(static function (\Throwable $e): void {
    App::showError($e, false);
});

/**
 * load license
 */
$app->loadLicense();

/**
 * setup 専用の定数群
 *
 * install / メンテナンスの各エントリが共通で使う path 定数・ドメイン検証パターン・setup 自身の
 * ディレクトリ位置をここで確定する。以前は setup.php 冒頭で define していたが、setup.php の
 * クラス群（Detector / Surfacer 等）を autoload 対象の Services\Setup へ移したのに伴い、
 * ブートストラップである本ファイルのトップレベルへ集約した（PHPStan の定数収集を効かせるため、
 * メソッド内 define ではなくトップレベルで定義する）。
 */
ignore_user_abort(false);

if (!defined('PATH_CONFIG')) {
    define('PATH_CONFIG', SetupCommon::fixPathSeparator(SCRIPT_DIR . 'config.server.php'));
}
if (!defined('PATH_LICENSE')) {
    define('PATH_LICENSE', SetupCommon::fixPathSeparator(SCRIPT_DIR . 'license.php'));
}
if (!defined('PATH_HTACCESS')) {
    define('PATH_HTACCESS', SetupCommon::fixPathSeparator(SCRIPT_DIR . '.htaccess'));
}
if (!defined('PATH_ENV')) {
    define('PATH_ENV', SetupCommon::fixPathSeparator(SCRIPT_DIR . '.env'));
}
if (!defined('PATH_ARCHIVES')) {
    define('PATH_ARCHIVES', SetupCommon::fixPathSeparator(SCRIPT_DIR . ARCHIVES_DIR));
}
if (!defined('PATH_MEDIA')) {
    define('PATH_MEDIA', SetupCommon::fixPathSeparator(SCRIPT_DIR . MEDIA_LIBRARY_DIR));
}
if (!defined('PATH_STORAGE')) {
    define('PATH_STORAGE', SetupCommon::fixPathSeparator(SCRIPT_DIR . MEDIA_STORAGE_DIR));
}
if (!defined('PATH_THEMES')) {
    define('PATH_THEMES', SetupCommon::fixPathSeparator(SCRIPT_DIR . THEMES_DIR));
}
if (!defined('REGEX_VALID_DOMAIN')) {
    define('REGEX_VALID_DOMAIN', '@^([a-zA-Z0-9]+[a-zA-Z0-9-]*(?<=[a-zA-Z0-9])\.)+[a-zA-Z]+[a-zA-Z0-9-]*(?<=[a-zA-Z0-9])\.?$|^(?:\d{1,3}\.){3}\d{1,3}$|^localhost$@'); // phpcs:ignore
}

if (!defined('CACHE_DIR')) {
    define('CACHE_DIR', 'cache/');
}
if (!defined('PATH_CACHE')) {
    define('PATH_CACHE', SetupCommon::fixPathSeparator(SCRIPT_DIR . CACHE_DIR));
}

$setupDirPath = SetupCommon::fixPathSeparator(dirname(isset($_SERVER['SCRIPT_FILENAME']) ? (string)$_SERVER['SCRIPT_FILENAME'] : ''));
if (!defined('SETUP_DIR')) {
    define('SETUP_DIR', preg_replace('@^.*/(.*)$@si', '$1', $setupDirPath));
}
// 実行中エントリ（setup ディレクトリ）の絶対パス。テンプレート解決の基点。
if (!defined('SETUP_PATH')) {
    define('SETUP_PATH', $setupDirPath . '/');
}

if (!defined('HTTP_ROOT')) {
    $setupBaseUrl = (HTTPS ? 'https' : 'http') . '://' . HTTP_HOST . (!!HTTP_PORT ? ':' . HTTP_PORT : '') . '/';
    define('HTTP_ROOT', rtrim($setupBaseUrl . DIR_OFFSET, '/') . '/');
}
if (!defined('ROOT_DIR')) {
    define('ROOT_DIR', SetupCommon::fixPathSeparator(preg_replace('@' . SETUP_DIR . '$@', '', $setupDirPath)));
}
