<?php

namespace App\Core;

use \Exception;

/**
 * Decides what is allowed and what not
 * TODO: ...
 */
class AccessControl
{
    public App $app;

    private array  $acl;
    private string $currentPage;

    public function __construct(App $app)
    {
        $this->app = $app;

        $this->acl = [
            // routes that need power level 1 and up
            [
                "routes" => [
                    "race/simulator.php",
                    "race/configure/*"
                ],
                "catcher" => [
                    "name" => "page",
                    "args" => 1,
                ],
            ],
            // routes that dont need any auth
            [
                "routes" => [
                    "*"
                ],
                "catcher" => [
                    "name" => "nothing",
                ],
            ]
        ];

        $this->currentPage = substr(
            $_SERVER["SCRIPT_NAME"],
            strlen($this->app->config["root_url"])
        );

        // TODO: add error handling
        foreach ($this->acl as $key => $value)
        {
            $routes  = $value["routes"];
            $catcher = $value["catcher"];

            foreach ($routes as $key => $value)
            {
                // if the end of the route is an asterisk we match everything after it
                if ($value[-1] == '*')
                {
                    // remove asterisk
                    $value = substr($value, 0, -1);
                    // check if string starts with
                    if (strncmp($this->currentPage, $value, strlen($value)) !== 0)
                    {
                        continue;
                    }
                } else {
                    // end is not an asterisk, match full string
                    if ($value !== $this->currentPage)
                    {
                        continue;
                    }
                }

                if (isset($catcher["args"]))
                {
                    call_user_func([$this, $catcher["name"]], $catcher["args"]);
                } else {
                    call_user_func([$this, $catcher["name"]]);
                }

                return;
            }
        }

        throw new Exception("Could not find current page in access control list, did you add it?");
    }

    private function page(int $powerLevel): void
    {
        if (!$this->app->user->loggedIn || !($this->app->user->powerLevel >= $powerLevel))
        {
            http_response_code(401);
            $this->app->view("template/header", ["title" => "Ingen tilgang!"]);
            $this->app->view("App/Core/AccessControl/unauthorized");
            $this->app->view("template/footer");
            die();
        }
    }

    /**
     * Does... nothing! For when the page does not need any access control.
     */
    private function nothing(): void
    {
        return;
    }
}