<?php
declare(strict_types=1);

namespace App\DataProvider\Core;

use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use App\ApiResources\DownloadRequest;
use App\Enum\Core\FileStatusEnum;
use App\Repository\Core\FileRepository;
use App\Service\File\FileManager;
use Symfony\Component\HttpFoundation\HeaderUtils;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;

/**
 * Custom provider pour le téléchargement des fichiers du LocalStorage
 */
final class DownloadRequestDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
{
    public function __construct(
        private FileRepository $fileRepository,
        private FileManager $fileManager
    )
    {}

    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
    {
        return DownloadRequest::class === $resourceClass;
    }

    public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): Response | RedirectResponse
    {
        $file = $this->fileRepository->find($id);
        if (empty($file)) {
            throw new \RuntimeException("File " . $id . " does not exist; abort.");
        }
        if ($file->getStatus() !== FileStatusEnum::READY()->getValue()) {
            throw new \RuntimeException("File " . $id . " has " . $file->getStatus() . " status; abort.");
        }

        // Read the file
        $content = $this->fileManager->read($file);

        // Build the response and attach the file to it
        // @see https://symfony.com/doc/current/components/http_foundation.html#serving-files
        $response = new Response($content);

        $response->headers->set('Charset', 'UTF-8');
        $response->headers->set('Access-Control-Expose-Headers', 'Content-Disposition');

        if (!empty($file->getMimeType())) {
            $response->headers->set('Content-Type', $file->getMimeType());
        }

        $response->headers->set(
            'Content-Disposition',
            HeaderUtils::makeDisposition(HeaderUtils::DISPOSITION_ATTACHMENT, $file->getName())
        );

        return $response;
    }
}
