<?php
declare(strict_types=1);

namespace App;

use Authentication\AuthenticationService;
use Authentication\AuthenticationServiceInterface;
use Authentication\AuthenticationServiceProviderInterface;
use Authentication\Middleware\AuthenticationMiddleware;
use Cake\Core\ContainerInterface;
use Cake\Error\Middleware\ErrorHandlerMiddleware;
use Cake\Http\BaseApplication;
use Cake\Http\Middleware\BodyParserMiddleware;
use Cake\Http\Middleware\CsrfProtectionMiddleware;
use Cake\Http\MiddlewareQueue;
use Cake\Routing\Middleware\AssetMiddleware;
use Cake\Routing\Middleware\RoutingMiddleware;
use Cake\Routing\Router;
use Psr\Http\Message\ServerRequestInterface;

class Application extends BaseApplication implements AuthenticationServiceProviderInterface
{
    public function bootstrap(): void
    {
        parent::bootstrap();
    }

    public function middleware(MiddlewareQueue $queue): MiddlewareQueue
    {
        return $queue
            ->add(new ErrorHandlerMiddleware())
            ->add(new AssetMiddleware())
            ->add(new RoutingMiddleware($this))
            ->add(new BodyParserMiddleware())
            ->add(new AuthenticationMiddleware($this))
            ->add(new CsrfProtectionMiddleware([
                'cookieName' => 'csrfToken',
                'httponly'   => true,
                'secure'     => true,
                'samesite'   => 'Lax',
            ]));
    }

    public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
    {
        $loginUrl = Router::url('/', false);

        return new AuthenticationService([
            'unauthenticatedRedirect' => $loginUrl,
            'queryParam'              => 'redirect',

            'identifiers' => [
                'Authentication.Password' => [
                    'fields'   => ['username' => 'email', 'password' => 'password'],
                    'resolver' => [
                        'className' => 'Authentication.Orm',
                        'userModel' => 'Login',
                    ],
                ],
            ],

            'authenticators' => [
                'Authentication.Form' => [
                    'loginUrl'     => $loginUrl,
                    'fields'       => ['username' => 'email', 'password' => 'password'],
                    'urlChecker'   => 'Authentication.Default',
                    'checkFullUrl' => false,
                ],
                'Authentication.Session',
            ],
        ]);
    }

    public function services(ContainerInterface $container): void
    {
    }
}
