<?php

/**
 * Created by PhpStorm.
 * User: ondra
 * Date: 13.12.17
 * Time: 8:08.
 */

namespace KupShop\AdminBundle\Controller;

use KupShop\AdminBundle\Util\AdminClassLocator;
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Routing\AdminRoute;
use KupShop\KupShopBundle\Util\System\PathFinder;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class AdminController extends AbstractController
{
    public function __construct()
    {
        $cfg = Config::get();

        require_once './engine/admin/functions.php';
    }

    /**
     * @AdminRoute("/")
     * @AdminRoute("/index.php")
     */
    public function indexAction(PathFinder $pathFinder)
    {
        $response = new StreamedResponse(function () use ($pathFinder) {
            global $cfg, $dbcfg, $adminID, $ctrl, $publicArea;

            $publicArea = true;

            require_once $pathFinder->getAdminDir().'common.php';

            require_once $pathFinder->getAdminDir().'index.php';
        });

        return $response;
    }

    /**
     * @AdminRoute("/launch.php")
     */
    public function launchAction(AdminClassLocator $adminClassLocator, PathFinder $pathFinder, Request $request, ContextManager $contextManager)
    {
        $response = new StreamedResponse(function () use ($adminClassLocator, $pathFinder, $contextManager) {
            global $cfg, $dbcfg, $adminID, $ctrl, $txt_str, $adminRights;

            require_once $pathFinder->getAdminDir().'common.php';

            $contextManager->forceEmptyContexts();

            $script = '';
            if (isset($_GET['s'])) {
                $script = $_GET['s'];
                if ($script == 'symfony') {
                    $script = 'main.php';
                }

                // odstraneni relativnich adres
                $script = preg_replace('@^(\\.{0,2}/)+@', '', $script);
                $script = preg_replace('@\\.{1,2}/@', '', $script);

                // odstraneni HTTP ze zacatku
                $script = preg_replace('@^(http|ftp|https|mms)://@', '', $script);

                // kdyz se nejedna o soubor php
                if (!preg_match('@.+\\.php$@', $script)) {
                    $script = '';
                }
            }

            if ($script == '') {
                $script = 'main.php';
            }

            $classPath = $script;

            function loadScript($file)
            {
                global $cfg, $dbcfg, $ctrl;

                $return = require_once $file;

                if (is_string($return)) {
                    $main_class = $return;
                }

                if (!empty($main_class)) {
                    $instance = new $main_class();
                    $instance->run();
                }
            }

            $classPath = $adminClassLocator->getClassPath($script);

            try {
                if (file_exists($classPath)) {
                    loadScript($classPath);
                } else {
                    // zalogovat chybu
                    logError(__FILE__, __LINE__, 'LAUNCH.PHP INCLUDE ERROR s='.$_GET['s']);

                    $classPath = $cfg['Path']['shared_version'].'admin/main.php';
                    loadScript($classPath);
                }
            } catch (AccessDeniedException|NotFoundHttpException $e) {
                $this->handleAccessDeniedOrNotFoundException($e);
            }
        });

        if ($request->cookies->get('wpjRequestNotFinished', false) && $_GET['s'] != 'checktimeout.php') {
            $response->headers->clearCookie('wpjRequestNotFinished');
        }

        if (isLocalDevelopment() && $request->cookies->get('wpjSymfonyToolbarDebug')) {
            ob_start();
            $response->sendContent();
            $data = ob_get_clean();
            ob_end_clean();

            return new Response($data, $response->getStatusCode(), $response->headers->all());
        }

        return $response;
    }

    private function handleAccessDeniedOrNotFoundException(AccessDeniedException|NotFoundHttpException $exception): void
    {
        $smarty = createSmarty(true);
        $smarty->assign(['exception' => $exception]);

        $code = $exception instanceof NotFoundHttpException ? $exception->getStatusCode() : $exception->getCode();

        $smarty->display("error.{$code}.tpl");
    }
}
