<?php

namespace AutoAdmin\Bundle\Content\Routing;

use AutoAdmin\Bundle\Core\Helper\DoctrineHelper;
use Traversable;

class AutoRouterManager
{
    /**
     * @var array<ContentAutoRouterInterface>
     */
    protected array $routers;

    protected array $refs = [];

    public function __construct(Traversable $guessers)
    {
        $this->routers = array_map([$this, 'addRouter'], iterator_to_array($guessers));
    }

    public function generate(
        ContentRouter $contentRouter,
        object $subject,
        ?string $route,
        array $parameters = [],
        array $options = []
    ) {
        if (array_key_exists($contentKey = $this->createKey($subject), $this->refs)) {
            return $this->refs[$contentKey];
        }

        $url = null;
        foreach ($this->routers as $router) {
            if ($router->supports($subject)) {
                $url = $router->buildUrl($contentRouter, $subject, $route, $parameters, $options);
                break;
            }
        }

        if ($subject && !empty($contentKey)) {
            $this->refs[$contentKey] = $url;
        }

        return $url;
    }

    protected function createKey(object $content): string
    {
        // we were previously using "id and class" or "spl object id" for indexes but this wasn't working with object mutations,
        // also tried php serialize, wasn't doing good with closures
        // also tried symfony serializer, wasn't fast enough (probably too much info kept/processed)

        // We can now use mutations + cloning to generate multiple urls from one given object (cf. AL cocoons)

        $objString = DoctrineHelper::getClass($content). '#'.$content->getId().'~'.spl_object_id($content);

        return $objString;
    }

    protected function addRouter(ContentAutoRouterInterface $router): ContentAutoRouterInterface
    {
        return $router;
    }
}
