<?php

declare(strict_types=1);

use Fennec\Autoload\Autoloader;
use Fennec\Clock\SystemClock;
use Fennec\Config\Config;
use Fennec\Container\Container;
use Fennec\Exception\ExceptionHandler;
use Fennec\Http\Request;
use Fennec\Kernel\Kernel;
use Fennec\Reflection\DirectoryClassFinder;
use Fennec\Routing\RouteCache;
use Fennec\Routing\Router;
use Fennec\Routing\RouteScanner;
use Fennec\Security\AuthenticationMiddleware;
use Fennec\Security\Firewall;
use Fennec\Security\Jwt\Jwt;

require dirname(__DIR__) . '/fennec/src/Autoload/Autoloader.php';

$rootPath = dirname(__DIR__);

$autoloader = new Autoloader();
$autoloader->addNamespace('Fennec\\', $rootPath . '/fennec/src');
$autoloader->addNamespace('App\\', $rootPath . '/src');
$autoloader->register();

$config = Config::fromFile($rootPath . '/.env.local');

$routeCache = new RouteCache($rootPath . '/var/cache/routes.php');
$router = new Router(
    $routeCache->exists()
        ? $routeCache->read()
        : (new RouteScanner(new DirectoryClassFinder()))->scanDirectory('App\\Controller', $rootPath . '/src/Controller'),
);

$firewall = Firewall::fromConfigFile($rootPath . '/config/firewall.php');

$jwt = new Jwt(
    (string) $config->get('JWT_SECRET'),
    (int) $config->get('JWT_TTL', 3600),
    new SystemClock(),
);

$container = new Container();
$container->instance(Config::class, $config);

$kernel = new Kernel(
    $router,
    $firewall,
    $container,
    new AuthenticationMiddleware($jwt),
    new ExceptionHandler((bool) $config->get('APP_DEBUG', false)),
);

$kernel->handle(Request::fromGlobals())->send();
