<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Filesystem\PublicUri;

use Contao\CoreBundle\Filesystem\PublicUri\Options;
use Contao\CoreBundle\Filesystem\PublicUri\PublicUriProviderInterface;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\Local\LocalFilesystemAdapter;
use Nyholm\Psr7\Uri;
use Psr\Http\Message\UriInterface;
use Symfony\Component\HttpFoundation\UriSigner;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class StoragePublicUriProvider implements PublicUriProviderInterface
{
    /**
     * @var \WeakMap<LocalFilesystemAdapter, string>
     */
    private \WeakMap $adapters;

    public function __construct(private readonly UrlGeneratorInterface $urlGenerator, private readonly UriSigner $uriSigner)
    {
        $this->adapters = new \WeakMap();
    }

    public function registerAdapter(LocalFilesystemAdapter $adapter, string $name): void
    {
        $this->adapters[$adapter] = $name;
    }

    /**
     * Generates public URLs for the symlinked local files, so that they can be
     * provided directly by the web server.
     */
    public function getUri(FilesystemAdapter $adapter, string $adapterPath, ?Options $options): ?UriInterface
    {
        if ($options || null === ($storage = ($this->adapters[$adapter] ?? null))) {
            return null;
        }

        $url = $this->urlGenerator->generate('storage_public_path', ['storage' => $storage, 'path' => $adapterPath, 't' => new \DateTimeImmutable('+30 minutes')->format('c')], UrlGeneratorInterface::ABSOLUTE_URL);

        return new Uri($this->uriSigner->sign($url));
    }
}
