<commit_before><?php

declare(strict_types=1);

/*
 * This file is part of the Valkyrja Framework package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Valkyrja\Routing\Annotation\Annotators;

use InvalidArgumentException;
use ReflectionException;
use Valkyrja\Annotation\Annotator;
use Valkyrja\Annotation\Filter;
use Valkyrja\Container\Container;
use Valkyrja\Reflection\Reflector;
use Valkyrja\Routing\Annotation\Enums\Annotation;
use Valkyrja\Routing\Annotation\Route;
use Valkyrja\Routing\Annotation\RouteAnnotator as Contract;
use Valkyrja\Routing\Exceptions\InvalidRoutePath;
use Valkyrja\Routing\Models\Route as RouteModel;
use Valkyrja\Routing\Route as RouteContract;
use Valkyrja\Container\Support\Provides;

use function array_merge;
use function trim;

/**
 * Class RouteAnnotator.
 *
 * @author <NAME>
 */
class RouteAnnotator implements Contract
{
    use Provides;

    /**
     * The annotator.
     *
     * @var Annotator
     */
    protected Annotator $annotator;

    /**
     * The filter.
     *
     * @var Filter
     */
    protected Filter $filter;

    /**
     * The reflector.
     *
     * @var Reflector
     */
    protected Reflector $reflector;

    /**
     * ContainerAnnotator constructor.
     *
     * @param Annotator $annotator
     * @param Filter    $filter
     * @param Reflector $reflector
     */
    public function __construct(Annotator $annotator, Filter $filter, Reflector $reflector)
    {
        $this->annotator = $annotator;
        $this->filter    = $filter;
        $this->reflector = $reflector;
    }

    /**
     * The items provided by this provider.
     *
     * @return array
     */
    public static function provides(): array
    {
        return [
            Contract::class,
        ];
    }

    /**
     * Publish the provider.
     *
     * @param Container $container The container
     *
     * @return void
     */
    public static function publish(Container $container): void
    {
        $container->setSingleton(
            Contract::class,
            new static(
                $container->getSingleton(Annotator::class),
                $container->getSingleton(Filter::class),
                $container->getSingleton(Reflector::class)
            )
        );
    }

    /**
     * Get routes.
     *
     * @param string ...$classes The classes
     *
     * @throws ReflectionException
     * @throws InvalidRoutePath
     * @throws InvalidArgumentException
     *
     * @return RouteContract[]
     */
    public function getRoutes(string ...$classes): array
    {
        $routes = $this->getClassRoutes($classes);
        /** @var RouteContract[] $finalRoutes */
        $finalRoutes = [];

        // Iterate through all the routes
        foreach ($routes as $route) {
            if (! $route->getClass() || ! $route->getPath()) {
                throw new InvalidArgumentException('Invalid class or path defined in route.');
            }

            // Set the route's properties
            $this->setRouteProperties($route);

            // Get the class's annotations
            $classAnnotations = $this->getClassAnnotations($route->getClass());

            // If this route's class has annotations
            if (! empty($classAnnotations)) {
                /** @var Route $annotation */
                // Iterate through all the annotations
                foreach ($classAnnotations as $annotation) {
                    // And set a new route with the controller defined annotation additions
                    $finalRoutes[] = $this->getRouteFromAnnotation($this->getControllerBuiltRoute($annotation, $route));
                }
            } else {
                // Validate the path before setting the route
                $route->setPath($this->validatePath($route->getPath()));

                // Otherwise just set the route in the final array
                $finalRoutes[] = $this->getRouteFromAnnotation($route);
            }
        }

        return $finalRoutes;
    }

    /**
     * Get all classes' routes.
     *
     * @param array $classes The classes
     *
     * @throws ReflectionException
     *
     * @return RouteContract[]
     */
    protected function getClassRoutes(array $classes): array<commit_msg>Fixing Scrutinizer issues.<commit_after><?php

declare(strict_types=1);

/*
 * This file is part of the Valkyrja Framework package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Valkyrja\Routing\Annotation\Annotators;

use InvalidArgumentException;
use ReflectionException;
use Valkyrja\Annotation\Annotator;
use Valkyrja\Annotation\Filter;
use Valkyrja\Container\Container;
use Valkyrja\Reflection\Reflector;
use Valkyrja\Routing\Annotation\Enums\Annotation;
use Valkyrja\Routing\Annotation\Route;
use Valkyrja\Routing\Annotation\RouteAnnotator as Contract;
use Valkyrja\Routing\Exceptions\InvalidRoutePath;
use Valkyrja\Routing\Models\Route as RouteModel;
use Valkyrja\Routing\Route as RouteContract;
use Valkyrja\Container\Support\Provides;

use function array_merge;
use function trim;

/**
 * Class RouteAnnotator.
 *
 * @author <NAME>
 */
class RouteAnnotator implements Contract
{
    use Provides;

    /**
     * The annotator.
     *
     * @var Annotator
     */
    protected Annotator $annotator;

    /**
     * The filter.
     *
     * @var Filter
     */
    protected Filter $filter;

    /**
     * The reflector.
     *
     * @var Reflector
     */
    protected Reflector $reflector;

    /**
     * ContainerAnnotator constructor.
     *
     * @param Annotator $annotator
     * @param Filter    $filter
     * @param Reflector $reflector
     */
    public function __construct(Annotator $annotator, Filter $filter, Reflector $reflector)
    {
        $this->annotator = $annotator;
        $this->filter    = $filter;
        $this->reflector = $reflector;
    }

    /**
     * The items provided by this provider.
     *
     * @return array
     */
    public static function provides(): array
    {
        return [
            Contract::class,
        ];
    }

    /**
     * Publish the provider.
     *
     * @param Container $container The container
     *
     * @return void
     */
    public static function publish(Container $container): void
    {
        $container->setSingleton(
            Contract::class,
            new static(
                $container->getSingleton(Annotator::class),
                $container->getSingleton(Filter::class),
                $container->getSingleton(Reflector::class)
            )
        );
    }

    /**
     * Get routes.
     *
     * @param string ...$classes The classes
     *
     * @throws ReflectionException
     * @throws InvalidRoutePath
     * @throws InvalidArgumentException
     *
     * @return RouteContract[]
     */
    public function getRoutes(string ...$classes): array
    {
        $routes = $this->getClassRoutes($classes);
        /** @var RouteContract[] $finalRoutes */
        $finalRoutes = [];

        // Iterate through all the routes
        foreach ($routes as $route) {
            $class = $route->getClass();
            $path = $route->getPath();

            if (null === $class || null === $path) {
                throw new InvalidArgumentException('Invalid class or path defined in route.');
            }

            // Set the route's properties
            $this->setRouteProperties($route);

            // Get the class's annotations
            $classAnnotations = $this->getClassAnnotations($class);

            // If this route's class has annotations
            if (! empty($classAnnotations)) {
                /** @var Route $annotation */
                // Iterate through all the annotations
                foreach ($classAnnotations as $annotation) {
                    // And set a new route with the controller defined annotation additions
                    $finalRoutes[] = $this->getRouteFromAnnotation($this->getControllerBuiltRoute($annotation, $route));
                }
            } else {
                // Validate the path before setting the route
                $route->setPath($this->validatePath($path));

                // Otherwise just set the route in the final array
                $finalRoutes[] = $this->getRouteFromAnnotation($route);
            }
        }

        return $finalRoutes;
    }

    /**
     * Get all classes' routes.
     *
     * @param array $classes The classes
     *
     * @throws ReflectionException
     *
     * @return RouteContract[]
     */
    protected function getClassRoutes(array $classes): array
{'fraction_non_alphanumeric': 0.10668934240362812, 'fraction_numerical': 0.00022675736961451248, 'mean_word_length': 2.1092703560098696, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 47, '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': '4625811', 'n_tokens_mistral': 2402, 'n_tokens_neox': 2360, 'n_words': 605}