<commit_before><?php
declare(strict_types = 1);
/**
 * /src/Rest/Describer/ApiDocDescriber.php
 *
 * @author  TLe, <NAME> <<EMAIL>>
 */
namespace App\Rest\Describer;

use App\Annotation\RestApiDoc;
use App\Rest\Doc\RouteModel;
use Closure;
use Doctrine\Common\Annotations\AnnotationReader;
use EXSyst\Component\Swagger\Swagger;
use InvalidArgumentException;
use Nelmio\ApiDocBundle\Describer\DescriberInterface;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RouterInterface;
use UnexpectedValueException;
use function array_filter;
use function array_map;
use function array_values;
use function count;
use function explode;
use function mb_strrpos;
use function mb_strtolower;

/**
 * Class ApiDocDescriber
 *
 * @package App\Rest\Describer
 * @author  TLe, <NAME> <<EMAIL>>
 */
class ApiDocDescriber implements DescriberInterface
{
    /**
     * @var RouteCollection
     */
    private $routeCollection;

    /**
     * @var Rest
     */
    private $rest;

    /**
     * @var AnnotationReader
     */
    private $annotationReader;

    /**
     * @var Swagger
     */
    private $api;

    /**
     * @param RouterInterface $router
     * @param Rest            $rest
     *
     * @throws \Doctrine\Common\Annotations\AnnotationException
     */
    public function __construct(RouterInterface $router, Rest $rest)
    {
        $this->routeCollection = $router->getRouteCollection();
        $this->rest = $rest;
        $this->annotationReader = new AnnotationReader();
    }

    /**
     * @param Swagger $api
     *
     * @throws InvalidArgumentException
     * @throws ReflectionException
     * @throws UnexpectedValueException
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \Twig_Error_Loader
     * @throws \Twig_Error_Runtime
     * @throws \Twig_Error_Syntax
     */
    public function describe(Swagger $api): void
    {
        $this->api = $api;

        foreach ($this->getRouteModels() as $routeModel) {
            $path = $api->getPaths()->get($routeModel->getRoute()->getPath());

            if ($path->hasOperation($routeModel->getHttpMethod())) {
                $this->rest->createDocs($path->getOperation($routeModel->getHttpMethod()), $routeModel);
            }
        }
    }

    /**
     * @return RouteModel[]
     *
     * @throws ReflectionException
     */
    private function getRouteModels(): array
    {
        $annotationFilterMethod = $this->getClosureAnnotationFilterMethod();
        $annotationFilterRoute = $this->getClosureAnnotationFilterRoute();

        $iterator = function (Route $route) use ($annotationFilterMethod, $annotationFilterRoute): RouteModel {
            [$controller, $method] = explode('::', $route->getDefault('_controller'));

            $reflection = new ReflectionMethod($controller, $method);
            $methodAnnotations = $this->annotationReader->getMethodAnnotations($reflection);
            $controllerAnnotations = $this->annotationReader->getClassAnnotations($reflection->getDeclaringClass());

            /** @var Method $httpMethodAnnotation */
            $httpMethodAnnotation = array_values(array_filter($methodAnnotations, $annotationFilterMethod))[0];

            /** @var \Sensio\Bundle\FrameworkExtraBundle\Configuration\Route $routeAnnotation */
            $routeAnnotation = array_values(array_filter($controllerAnnotations, $annotationFilterRoute))[0];

            $routeModel = new RouteModel();
            $routeModel->setController($controller);
            $routeModel->setMethod($method);
            $routeModel->setHttpMethod(mb_strtolower($httpMethodAnnotation->getMethods()[0]));
            $routeModel->setBaseRoute($routeAnnotation->getPath());
            $routeModel->setRoute($route);
            $routeModel->setMethodAnnotations($methodAnnotations);
            $routeModel->setControllerAnnotations($controllerAnnotations);<commit_msg>refactor: fixed psalm errors<commit_after><?php
declare(strict_types = 1);
/**
 * /src/Rest/Describer/ApiDocDescriber.php
 *
 * @author  TLe, <NAME> <<EMAIL>>
 */
namespace App\Rest\Describer;

use App\Annotation\RestApiDoc;
use App\Rest\Doc\RouteModel;
use Closure;
use Doctrine\Common\Annotations\AnnotationReader;
use EXSyst\Component\Swagger\Swagger;
use InvalidArgumentException;
use Nelmio\ApiDocBundle\Describer\DescriberInterface;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RouterInterface;
use UnexpectedValueException;
use function array_filter;
use function array_map;
use function array_values;
use function count;
use function explode;
use function mb_strrpos;
use function mb_strtolower;

/**
 * Class ApiDocDescriber
 *
 * @package App\Rest\Describer
 * @author  TLe, <NAME> <<EMAIL>>
 */
class ApiDocDescriber implements DescriberInterface
{
    /**
     * @var RouteCollection
     */
    private $routeCollection;

    /**
     * @var Rest
     */
    private $rest;

    /**
     * @var AnnotationReader
     */
    private $annotationReader;

    /**
     * @var Swagger
     */
    private $api;

    /**
     * @param RouterInterface $router
     * @param Rest            $rest
     *
     * @throws \Doctrine\Common\Annotations\AnnotationException
     */
    public function __construct(RouterInterface $router, Rest $rest)
    {
        $this->routeCollection = $router->getRouteCollection();
        $this->rest = $rest;
        $this->annotationReader = new AnnotationReader();
    }

    /**
     * @param Swagger $api
     *
     * @throws InvalidArgumentException
     * @throws ReflectionException
     * @throws UnexpectedValueException
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \Twig_Error_Loader
     * @throws \Twig_Error_Runtime
     * @throws \Twig_Error_Syntax
     */
    public function describe(Swagger $api): void
    {
        $this->api = $api;

        foreach ($this->getRouteModels() as $routeModel) {
            $path = $api->getPaths()->get($routeModel->getRoute()->getPath());

            if ($path->hasOperation($routeModel->getHttpMethod())) {
                $this->rest->createDocs($path->getOperation($routeModel->getHttpMethod()), $routeModel);
            }
        }
    }

    /**
     * @return RouteModel[]|array<mixed, mixed>
     *
     * @throws ReflectionException
     */
    private function getRouteModels(): array
    {
        $annotationFilterMethod = $this->getClosureAnnotationFilterMethod();
        $annotationFilterRoute = $this->getClosureAnnotationFilterRoute();

        $iterator = function (Route $route) use ($annotationFilterMethod, $annotationFilterRoute): RouteModel {
            [$controller, $method] = explode('::', $route->getDefault('_controller'));

            $reflection = new ReflectionMethod($controller, $method);
            $methodAnnotations = $this->annotationReader->getMethodAnnotations($reflection);
            $controllerAnnotations = $this->annotationReader->getClassAnnotations($reflection->getDeclaringClass());

            /** @var Method $httpMethodAnnotation */
            $httpMethodAnnotation = array_values(array_filter($methodAnnotations, $annotationFilterMethod))[0];

            /** @var \Sensio\Bundle\FrameworkExtraBundle\Configuration\Route $routeAnnotation */
            $routeAnnotation = array_values(array_filter($controllerAnnotations, $annotationFilterRoute))[0];

            $routeModel = new RouteModel();
            $routeModel->setController($controller);
            $routeModel->setMethod($method);
            $routeModel->setHttpMethod(mb_strtolower($httpMethodAnnotation->getMethods()[0]));
            $routeModel->setBaseRoute($routeAnnotation->getPath());
            $routeModel->setRoute($route);
            $routeModel->setMethodAnnotations($methodAnnotations);
            $routeModel->setControllerAnnotations($controllerAnnotations);
{'fraction_non_alphanumeric': 0.12227966814957317, 'fraction_numerical': 0.00096188529517855, 'mean_word_length': 3.348144276006273, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 82, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '960727', 'n_tokens_mistral': 2278, 'n_tokens_neox': 2231, 'n_words': 403}