<?php
require_once "lib/dynamic_style.php";
require_once "lib/script_data.php";
/**
 * Loads and returns the result of a PHP file.
 * This function is typically used to process dynamic content of a page.
 * It simply scopes an external file into a function to prevent variable conflicts.
 *
 * @param string $page_file The file path to the dynamic page.
 * @return array Returns the array of data generated by including the PHP file.
 */
function renderDynamicPage(string $page_file): array
{
    return require $page_file;
}

/**
 * Removes all HTML comments from the provided content string.
 *
 * @param string $content The HTML content from which to remove comments.
 * @return string The content without any HTML comments.
 */
function removeHtmlComments(string $content = '') :string {
    return preg_replace('/<!--(.|\s)*?-->/', '', $content);
}
/**
 * Parses custom `<page>` tags from the given input string and extracts parameters.
 * Returns the input string with `<page>` tags removed and a list of parameters.
 *
 * @param string $input The input HTML or text containing `<page>` tags.
 * @return array Returns an associative array with 'parameters' (parsed from the tag)
 *               and 'output' (the modified input string with `<page>` tags removed).
 */
function parsePageTag(string $input): array
{
    // Define the pattern for the tag
    $pattern = '/<page\s+([^>]+)><\/page>/i';

    // Check if the pattern matches the input
    if (preg_match($pattern, $input, $matches)) {
        // Extract parameters
        $parameters = [];
        if (preg_match_all('/(\w+)="([^"]+)"/', $matches[1], $paramMatches, PREG_SET_ORDER)) {
            foreach ($paramMatches as $paramMatch) {
                $parameters[$paramMatch[1]] = $paramMatch[2];
            }
        }

        // Remove the tag from the input
        $output = preg_replace($pattern, '', $input, 1);

        return ['parameters' => $parameters, 'output' => $output];
    }

    // If no match is found, return the original input
    return ['parameters' => [], 'output' => $input];
}
/**
 * Renders a page based on specified page and site names, handling dynamic and static content,
 * permissions, and error pages.
 *
 * @param string|null $page_name The name of the page to render. If null, uses default from request.
 * @param string|null $site_name The name of the site to render. If null, uses default from request.
 * @return array Returns an associative array containing the rendered page content, page name, site name, and page title.
 */
function renderPage(string $page_name = null, string $site_name = null): array
{
    global $routerConfig;
    global $routerRequest;

    if(!$site_name) {
        $site_name = $routerRequest["site_name"];
    }

    $site_title = str_replace("_", " ", $site_name);

    $site_title = ucfirst($site_title);

    if(!$page_name){
        $page_name = $routerRequest["page_name"];
    }

    $dynamic_page_file = $routerConfig["page_dir"] . $site_name . "/" . $page_name . ".php";
    $page_file = $routerConfig["page_dir"] . $site_name . "/" . $page_name . ".html";

    if (file_exists($dynamic_page_file)){
        $pageMetadata = renderDynamicPage($dynamic_page_file);

        $page = $pageMetadata["output"];
    }
    elseif (file_exists($page_file)){
        $page_tmp = file_get_contents($page_file);

        $pageMetadata = parsePageTag($page_tmp);
        $page = $pageMetadata["output"];
    }
    else{
        $page_tmp = file_get_contents($routerConfig["template_dir"] . "404.html");
        $pageMetadata = parsePageTag($page_tmp);
        $page = $pageMetadata["output"];
        http_response_code(404);
    }

    if(!empty($pageMetadata["parameters"]["minimal_permission_level"])){
        $page_required_permission = intval($pageMetadata["parameters"]["minimal_permission_level"]);
    }
    else{
        $page_required_permission = $routerConfig["page"]["default_permissions"];
    }

    if(!empty($pageMetadata["parameters"]["secret"])){
        $origSecret = $pageMetadata["parameters"]["secret"];
        if ($origSecret == "yes"){
            $is_secret_page = 1;
        }
        elseif ($origSecret == "no"){
            $is_secret_page = 0;
        }
        else{
            $is_secret_page = $routerConfig["page"]["default_secret"];
        }
    }
    else{
        $is_secret_page = $routerConfig["page"]["default_secret"];
    }


    if($page_required_permission > $_SESSION["privilege_level"]){
        if($is_secret_page == 1) {
            $page_tmp = file_get_contents($routerConfig["template_dir"] . "404.html");
            $pageMetadata = parsePageTag($page_tmp);
            $page = $pageMetadata["output"];
            http_response_code(404);
        }
        else{
            $page_tmp = file_get_contents($routerConfig["template_dir"] . "403.html");
            $pageMetadata = parsePageTag($page_tmp);
            $page = $pageMetadata["output"];
            http_response_code(403);
        }
    }

    $page = str_replace("__DEFAULT_LINK__", "/" . $routerConfig["default_site"] . "/" . $routerConfig["default_page"], $page);
    if(!is_string($page)){
        $page = "";
    }

    if(!empty($pageMetadata["parameters"]["page_title"])){
        $page_title = $pageMetadata["parameters"]["page_title"];
    }
    else{
        $page_title = $page_name;
    }

    $page_title = $routerConfig['site_prefix'] . " " .  $site_title . " " . $page_title;

    $page = str_replace("__TEMPLATE_PAGE_TITLE__", $page_title, $page);

    $page = removeHtmlComments($page);

    return [
        "PageContent" => $page,
        "PageName" => $page_name,
        "SiteName" => $site_name,
        "PageTitle" => $page_title,
    ];

}
/**
 * Compiles a complete web page by injecting dynamic elements into a template skeleton,
 * including headers, footers, and SEO tags.
 * It is used when not going to a page by AJAX to initialize everything.
 *
 * @param string|null $site_name_in The site name to be used; defaults from global configuration if null.
 * @param string|null $page_name_in The page name to be used; defaults from global configuration if null.
 * @return string The complete HTML content of the web page ready for display.
 */
function getPage(string $site_name_in = null, string $page_name_in = null): string
{
    $page_tmp = renderPage($page_name_in, $site_name_in);

    $page = $page_tmp["PageContent"];
    $page_name = $page_tmp["PageName"];
    $site_name = $page_tmp["SiteName"];
    global $routerConfig;

    $skeleton = file_get_contents($routerConfig["template_dir"] . "skeleton.html");

    $footer = file_get_contents($routerConfig["template_dir"] . "footer.html");

    $page_title = $page_tmp["PageTitle"];
    $dynamic_style = doDynamicStyling();
    $dynamic_script_data = [
        "currentPage" => $page_name,
        "currentSite" => $site_name,
        "currentTitle" => $page_title,
        "defaultPage" => $routerConfig["default_page"],
        "defaultSite" => $routerConfig["default_site"],
        "UserInfo_Privileges" => $_SESSION["privilege_level"],
    ];
    if(isLoggedIn()){
        $dynamic_script_data += [
            "UserInfo_FirstName" => $_SESSION["first_name"],
            "UserInfo_LastName" => $_SESSION["last_name"],
            "UserInfo_Nickname" => $_SESSION["nickname"],
            "UserInfo_Email" => $_SESSION["email"],
            "UserInfo_MinecraftNick" => $_SESSION["minecraft_nickname"],
        ];
    }
    $dynamic_script = generateScriptData($dynamic_script_data);

    $navigation = generateNavigation();

    $seo = array();


    if(!empty($pageMetadata["parameters"]["author"])){
        $seo["author"] = htmlspecialchars($pageMetadata["parameters"]["author"]);
    }
    else{
        $seo["author"] = $routerConfig["seo"]["author"];
    }

    if(!empty($pageMetadata["parameters"]["description"])){
        $seo["description"] = htmlspecialchars($pageMetadata["parameters"]["description"]);
    }
    else{
        $seo["description"] = $routerConfig["seo"]["description"];
    }

    if(!empty($pageMetadata["parameters"]["keywords"])){
        $seo["keywords"] = $routerConfig["seo"]["keywords"] . ", " . htmlspecialchars($pageMetadata["parameters"]["keywords"]);
    }
    else{
        $seo["keywords"] = $routerConfig["seo"]["keywords"];
    }

    $seo["generator"] = $routerConfig["seo"]["generator"];

    $seo["robots"] = $routerConfig["seo"]["robots"];

    $seo_stuff = "";

    foreach ($seo as $key => $value){
        $seo_stuff .= "<meta name='$key' content='$value'>\n";
    }

    $out = $skeleton;
    $out = str_replace("__TEMPLATE__NAV__", $navigation, $out);
    $out = str_replace("__TEMPLATE__PAGE__", $page, $out);
    $out = str_replace("__TEMPLATE__FOOTER__", $footer, $out);
    $out = str_replace("__TEMPLATE__DYNAMIC__SCRIPT__", $dynamic_script, $out);
    $out = str_replace("__TEMPLATE__DYNAMIC__STYLE__", $dynamic_style, $out);
    $out = str_replace("__TEMPLATE_SEO_STUFF__", $seo_stuff, $out);
    if($routerConfig["inlining"]) {
        require_once "lib/inliner.php";
        $out = inlineLocalStylesFromHref($out);
        $out = inlineScriptFromSrc($out);
    }
    return str_replace("__TEMPLATE_PAGE_TITLE__", $page_title, $out);
}
/**
 * Provides an API interface to get page details including content and meta-information for routing purposes.
 * This is what enables the page to never refresh.
 *
 * @param string $page_name The name of the page.
 * @param string $site_name The name of the site.
 * @return array Returns an array with status, page content, location URL, and title for the requested page.
 */
function getPageEndpoint(string $page_name, string $site_name) :array
{
    $page_location = "/" . $site_name . "/" . $page_name;
    $page_tmp = renderPage($page_name, $site_name);
    return [
        "Status" => "Success",
        "Page" => $page_tmp["PageContent"],
        "PageLocation" => $page_location,
        "PageTitle" => $page_tmp["PageTitle"],
    ];
}