<?php

namespace Shasoft\SamoyedCMG;

// Подключить скрипты
require_once __DIR__ '/../../../vendor/autoload.php';
require_once 
__DIR__ '/../../../scripts/class_Shasoft_SamoyedCMG_Service_Path.php';
require_once 
__DIR__ '/../../../scripts/class_Shasoft_STwig_Twig.php';
require_once 
__DIR__ '/../../../scripts/traitRoute/953cfcd7f84c4b29b7df467f9b8a3e69.php';
require_once 
__DIR__ '/../../../scripts/samoyed-cmg-demo.shasoft.com-UrlBuilder.php';

use 
Shasoft\Support\Values\Get;
use 
Shasoft\SamoyedCMG\Service\IRoute;
use 
Shasoft\SamoyedCMG\Service\IRequest;
use 
Shasoft\SamoyedCMG\Service\IService;
use 
Symfony\Component\HttpFoundation\Response;

// Информация о маршруте
class Route implements IRoute
{
    
// Аргументы маршрута
    
protected Get $args;
    
// Конструктор
    
public function __construct(array $args)
    {
        
$this->args = new Get($args);
    }
    
// Домен
    
public function host() : string
    
{
        return 
'samoyed-cmg-demo.shasoft.com';
    }    
    
// Маршрут
    
public function route() : string
    
{
        return 
'/middleware/show-images/$width';
    }
    
// Аргументы маршрута
    
public function args() : Get
    
{
        return 
$this->args;
    }    
    
// Имя маршрута
    
public function name() : ?string
    
{
        return 
'middleware.images';
    }
    
// Имя маршрута указано?
    
public function hasName() : bool
    
{
        return 
true;
    }
}

// Приложение маршрута
class AppRoute
{
    
// Трейт с функцией onRequest которая генерирует ответ
    
use \Shasoft\SamoyedCMG\AppRouteOnRequest;
    
// Аргументы маршрута
    
static protected array $argsRoute = [];
    
// Соответствие Сервис => Имя класса
    
protected static array $serviceName2Classname = [
        
"Shasoft\\SamoyedCMG\\Service\\IPath" => "Shasoft_SamoyedCMG_Service_Path",
        
"Shasoft\\STwig\\ITwig" => "Shasoft_STwig_Twig",
        
"Shasoft\\SamoyedCMG\\Service\\ITemplate" => "Shasoft_STwig_Twig",
        
"Shasoft\\SamoyedCMG\\Service\\IRequest" => "Shasoft_SamoyedCMG_Service_Request",
        
IRoute::class => "Shasoft_SamoyedCMG_Route"
    
];
    
// Список созданных сервисов
    
protected static array $instances = [];
    
// Получить сервис (или false в случае его отсутствия)
    
static public function getServiceSafe(string $serviceName) : IService|false
    
{
        
// Преобразовать идентификатор сервиса/имя интерфейса => имя класса
        
if (array_key_exists($serviceNameself::$serviceName2Classname)) {
            
// Имя метода создания
            
$methodName self::$serviceName2Classname[$serviceName];
            
// А может сервис уже создан?
            
if (array_key_exists($methodNameself::$instances)) {
                
// Вернуть созданный ранее сервис
                
return self::$instances[$methodName];
            } else {
                
// Проверить существование метода создания
                
if (method_exists(__CLASS__$methodName)) {
                    
// Вызвать метод по имени для создания сервиса
                    
$ret self::$methodName();
                    
// Записать сервис в КЕШ
                    
self::$instances[$methodName] = $ret;
                    
// Вернуть сервис
                    
return $ret;                
                }
            }
        }
        
// Исключение
        
return false;
    }
    
// Получить сервис
    
static public function getService(string $serviceName) : IService
    
{
        
$ret self::getServiceSafe($serviceName);
        
// Если сервис не определен
        
if ($ret===false) {
            
// Исключение
            
throw new \Exception("Сервиса " $serviceName " не существует!");
        }
        return 
$ret;
    }
    
// Сервис с информацией о маршруте
    
static protected function Shasoft_SamoyedCMG_Route(): \Shasoft\SamoyedCMG\Route
    
{
        return new 
\Shasoft\SamoyedCMG\Route(self::$argsRoute);
    }
    
// Shasoft\SamoyedCMG\Service\Path
    
static protected function Shasoft_SamoyedCMG_Service_Path() : \Shasoft\SamoyedCMG\Service\Path
    
{
        return new 
\Shasoft\SamoyedCMG\Service\Path(\Shasoft\SamoyedCMG\AppRoute::getService(\Shasoft\SamoyedCMG\Service\IRoute::class));
    }
    
// Shasoft\STwig\Twig
    
static protected function Shasoft_STwig_Twig() : \Shasoft\STwig\Twig
    
{
        return new 
\Shasoft\STwig\Twig(\Shasoft\SamoyedCMG\AppRoute::getService(\Shasoft\SamoyedCMG\Service\IPath::class));
    }
    
// Shasoft\SamoyedCMG\Service\Request
    
static protected function Shasoft_SamoyedCMG_Service_Request() : \Shasoft\SamoyedCMG\Service\Request
    
{
        return new 
\Shasoft\SamoyedCMG\Service\Request();
    }
    
// Посредники
    
static protected function onMiddlewares(IRequest $request): Response
    
{
    
// Выполнить посредник Shasoft\SDemo\Middleware\ModifyHeaderMiddleware
    
return (new \Shasoft\SDemo\Middleware\ModifyHeaderMiddleware())->handle($request, function($request) {
        
// Вызвать основную функцию генерации
        
$response self::onRequest($request);
        
// Если ответ в виде строки
        
if (is_string($response)) {
            
// то преобразовать строку в HTTP ответ
            
$response = new Response($response);
            
$response->prepare($request->getSymfonyRequest());
        }
        return 
$response;
                
    }, array (
  
'name' => 'SamoyedCMG',
));
    }
    
// Запуск
    
static public function run()
    {
        
//--------------------------------------------------------------------------------
        
try {
            
// Аргументы маршрута
            
if( array_key_exists('Z0b4416110'$_GET) ) {
                
// Запомнить значение
                
self::$argsRoute['width'] = $_GET['Z0b4416110'];
                
// Удалить значение из глобального массива
                
unset($_GET["Z0b4416110"]);        
            }
            
// Запрос
            
$request self::getService(IRequest::class);
            
// Сформировать ответ
            
$response self::onMiddlewares($request);
            
// Отправить ответ пользователю
            
$response->send();
        } catch (
\Exception $e) {
            
s_dump_error('Исключение ' get_class($e), $e);
        } catch (
\Error $e) {
            
s_dump_error('Ошибка ' get_class($e), $e);
        }
    }
}
// Запустить обработку запроса
AppRoute::run();