<?php

namespace pictpostpersonal;

const VERSION = '0.0.0';

/**
 * システム情報を取り扱うユーティリティクラス
 */
class Environment
{
    private static $demo_mode = false;
    private static $use_rewrite = false;
    private static $compatible_mode = false;
    public static $thumbs = [];
    function __construct() {}

    public static function InitEnvironment($setting)
    {
        self::$use_rewrite = $setting->getValue('use_rewrite', true);
        self::$demo_mode = defined("DEMO_MODE") && DEMO_MODE;
        self::$compatible_mode = file_exists('./view.php');

        //グローバル変数定義
        define('SITE_URL', self::getSiteUrl());
        define('BASE_URL', self::getBaseUrl());

        //サムネイルファイルのパスを確定する
        $theme = $setting->getValue('theme', '');
        $theme = preg_replace('/[^a-zA-Z0-9_\-]/', '', $theme); //英数字以外の文字をサニタイズ
        if (file_exists('./user_resource/thumb.png')) {
            self::$thumbs['thumb'] = SITE_URL .  '/user_resource/thumb.png';
        } else if ($theme != '' && file_exists("/themes/$theme/thumb.png")) {
            self::$thumbs['thumb'] = BASE_URL . '/theme/thumb.png';
        } else {
            self::$thumbs['thumb'] = SITE_URL .  '/system_resource/thumb.png';
        }

        if (file_exists('./user_resource/nsfw.png')) {
            self::$thumbs['nsfw'] = SITE_URL . '/user_resource/nsfw-img.png';
        } else if ($theme != '' && file_exists("./themes/$theme/thumb-nsfw.png")) {
            self::$thumbs['nsfw'] = '/theme/thumb-nsfw.png';
        } else {
            self::$thumbs['nsfw'] = '/system_resource/nsfw.png';
        }

        if (file_exists('./user_resource/nsfw-text.png')) {
            self::$thumbs['nsfw-text'] = SITE_URL .  '/user_resource/nsfw-text.png';
        } else if ($theme != '' && file_exists("./themes/$theme/nsfw-text.png")) {
            self::$thumbs['nsfw-text'] = BASE_URL . '/theme/nsfw-text.png';
        } else {
            self::$thumbs['nsfw-text'] = SITE_URL . '/system_resource/nsfw-text.png';
        }
    }

    /**
     * バージョン番号を取得する
     *
     * @return string
     * 
     */
    static public function getVersion(): string
    {
        return VERSION;
    }

    /**
     * 本環境がデモ環境であるか取得する
     *
     * @return bool
     * 
     */
    static public function isDemoMode(): bool
    {
        return self::$demo_mode ?? false;
    }

    /**
     * Rewriteが有効かどうかを取得する
     *
     * @return bool
     * 
     */
    static public function useRewrite(): bool
    {
        return self::$use_rewrite ?? false;
    }

    /**
     * 環境に合わせた記事URLのベース部分を取得する
     *
     * @return string
     * 
     */
    public static function getLogUrlBase(): string
    {
        if (self::$use_rewrite) {
            return SITE_URL . '/log/';
        }
        return SITE_URL . '/?q=';
    }

    /**
     * 環境に合わせた記事のURLパスを取得する
     * 取得されるURLパスはサイトトップからの相対URL。
     * 絶対URLとして使用する場合は SITE_URLと結合する。ex) full_url = SITE_URL . Environment::getLogUrl($article)
     *
     * @param array|string|null $article
     * @param string $args
     *
     * @return string
     *
     */
    public static function getLogUrl($article, string $args = ''): string
    {
        if ($article == null) {
            return '';
        }

        if (gettype($article) == 'array') {
            //ログデータそのものが渡された場合
            if ($article['alt_url']) {
                $target  = htmlspecialchars($article['alt_url']);
            } else {
                $target = $article['id'];
            }
        } else {
            //URLまたはIDが渡された場合
            $target = $article;
        }
        if (self::$use_rewrite) {
            if ($args) {
                $args = "/$args";
            }
            if (is_numeric($target)) {
                return "/log/{$target}{$args}";
            } else {
                return "/{$target}{$args}";
            }
        } else {
            if ($args) {
                $args = "&page=$args";
            }
            return "/?q={$target}{$args}";
        }
    }

    /**
     * mod_rewriteが動作しているかチェックする。
     * rewrite_ruteには mod_rewrie_check を rewrite.phpに書き換えるルールが必要。
     *
     * @return bool
     * 
     */
    static public function isModRewriteEnabled(): bool
    {
        // ベースURLを取得
        $site_url = self::getSiteUrl();

        // 確認用URLを作成
        $check_url = $site_url . '/mod_rewrite_check';

        // 確認用URLにHTTPリクエストを送信
        try {
            $response = file_get_contents($check_url);

            // レスポンスを確認
            if (strstr($response, 'mod_rewrite is enabled')) {
                return true;
            } else {
                return false;
            }
        } catch (\Exception $ex) {
            return false;
        }
    }


    /**
     * 互換モード動作を行うかどうか
     *
     * @return bool
     * 
     */
    static public function isCompatibleMode(): bool
    {
        return self::$compatible_mode;
    }

    /**
     * リクエストからサイト(PPP)のURLを取得する(PPPのルートURL)
     *
     * @return string PPPのルートURL。　https://example.com
     * 
     */
    static public function  getSiteUrl(): string
    {
        // プロトコルを取得
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? 'https://' : 'http://';

        // ホスト名を取得
        $host = $_SERVER['HTTP_HOST'];

        // スクリプト名を取得し、ルートまでのパスを算出
        $script_name = $_SERVER['SCRIPT_NAME'];
        $path = str_replace(basename($script_name), '', $script_name);

        // ベースURLを構築
        $base_url = $protocol . $host . $path;

        return trim($base_url, '/');
    }

    public static function getRootPath()
    {
        // スクリプト名を取得し、ルートまでのパスを算出
        $script_name = $_SERVER['SCRIPT_NAME'];
        $path = str_replace(basename($script_name), '', $script_name);

        return $path;
    }

    /**
     * API呼び出し用のベースURLを取得する
     *
     * @return string
     * 
     */
    static private function getBaseUrl(): string
    {
        if (self::$use_rewrite) {
            return self::getSiteUrl();
        } else {
            return self::getSiteUrl() . '/?c=';
        }
    }

    public static function getSystemUrl(): string
    {
        return self::getPathInfo()['system_root_rel'];
    }

    public static function getPathInfo(): array
    {
        $result = array();

        $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
        $host = $_SERVER['HTTP_HOST'];
        $url = $host . $_SERVER['SCRIPT_NAME'];
        $request = $_SERVER['REQUEST_URI'];
        //$request = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL);
        $request = urldecode($request);
        $request = $protocol . '://' . $host . $request;

        $url_dir = dirname($url);
        if (substr($url_dir, -1) == '/') {
            $url_dir = substr($url_dir, 0, -1);
        }
        //URL中、/が連続しているケースがあるので取り除く
        $url = preg_replace('#/+#', '/', $url);
        $url_dir = preg_replace('#/+#', '/', $url_dir);
        $url = $protocol . '://' . $url;
        $url_dir = $protocol . '://' . $url_dir;

        if (strpos($url, '/api/')) {
            $url_system_root = dirname($url_dir); //APIディレクトリ内なら1階層上
            $rel = '../';
        } else {
            $url_system_root = $url_dir;
            $rel = './';
        }

        $result['url_dir'] = $url_dir; //呼び出し元ファイルのディレクトリまでのURL
        $result['url_system_root'] = $url_system_root; //このシステムのルートディレクトリ
        $result['system_root_rel'] = $rel; //呼び出し元からシステムルートへの相対パス

        $tmp = str_replace($url_system_root . '/', '', $request);
        if (substr($tmp, 0, 1) == '/') {
            $tmp = '.' . $tmp;
        }
        $result['system_request'] = $tmp; //システムルートから見たリクエストURL

        return $result;
    }
}
