<?php

declare(strict_types=1);

namespace UtilityModule\Middleware;

use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Tuupola\Middleware\JwtAuthentication;
use Zend\Config\Config;
use Zend\Diactoros\Response\JsonResponse;
use Zend\Expressive\Application;
use Zend\Expressive\Router\Route;

class JwtMiddlewareFactory
{
    /** @var Config */
    private $aclConfig;

    /**
     * @param ContainerInterface $container
     * @return JwtAuthentication
     */
    public function __invoke(ContainerInterface $container): JwtAuthentication
    {
        $configArray = $container->get('config');
        /** @var Config $config */
        $config = new Config($configArray);
        $this->aclConfig = $config->get('acl_config');
        return new JwtAuthentication([
          "secret" => $this->aclConfig->get('hmac_key'),
          "path" => "/api",
          "ignore" => $this->getIgnoredRoutes($container),
          "secure" => true,
          "relaxed" => [
            "localhost",
            "granprize.dev.yvan.hu",
          ],
          "error" => function (ResponseInterface $response, $arguments) {
              $data["status"] = "error";
              $data["message"] = $arguments["message"];
              return new JsonResponse($data, 401);
          }
        ]);
    }

    /**
     * @param ContainerInterface $container
     * @return array
     */
    private function getIgnoredRoutes(ContainerInterface $container): array
    {
        $passThroughRoutes = [];

        /** @var Application $app */
        $app = $container->get(Application::class);
        $appRoutes = $app->getRoutes();

        $unguardedRoutes = $this->aclConfig->get('unguarded_routes', new Config([]))->toArray();
        /** @var Route $route */
        foreach ($appRoutes as $route) {
            if (in_array($route->getName(), $unguardedRoutes)) {
                $passThroughRoutes[] = $route->getPath();
            }
        }

        $unguardedPaths = $this->aclConfig->get('unguarded_paths', new Config([]))->toArray();
        foreach ($unguardedPaths as $path) {
            $passThroughRoutes[] = $path;
        }

        return $passThroughRoutes;
    }
}
