<?php
declare(strict_types=1);

namespace App\Service\File;

use ApiPlatform\Api\IriConverterInterface;
use ApiPlatform\Api\UrlGeneratorInterface as UrlGeneratorInterfaceApiPlatform;
use ApiPlatform\Metadata\Get;
use App\Entity\Core\File;
use App\Service\File\Exception\FileNotFoundException;
use App\Service\File\Factory\ImageFactory;
use App\Service\File\Storage\FileStorageInterface;
use App\Service\ServiceIterator\StorageIterator;

/**
 * Le gestionnaire de fichiers permet d'effectuer de nombreuses opérations sur les fichiers stockés dans les différents
 * FileStorage (lecture, écriture, suppression...)
 */
class FileManager
{
    public function __construct(
        protected readonly IriConverterInterface $iriConverter,
        protected readonly StorageIterator $storageIterator,
        protected readonly ImageFactory $imageFactory
    ) {}

    /**
     * Retourne le storage dans lequel le fichier demandé est supposé se trouver
     *
     * @param File $file
     * @return FileStorageInterface
     * @throws FileNotFoundException
     */
    public function getStorageFor(File $file): FileStorageInterface
    {
        return $this->storageIterator->getStorageFor($file);
    }

    /**
     * Lit le fichier et retourne son contenu
     *
     * @param File $file
     * @return string
     * @throws FileNotFoundException
     */
    public function read(File $file): string
    {
        $storage = $this->getStorageFor($file);
        return $storage->read($file);
    }

    /**
     * @param $file
     * @param $content
     * @param $requester
     * @return File
     * @throws FileNotFoundException
     */
    public function write($file, $content, $requester): File{
        $storage = $this->getStorageFor($file);
        return $storage->writeFile($file, $content, $requester);
    }

    /**
     * Lit le fichier Image et retourne une URL
     * @param File $file
     * @param string $size
     * @param bool $relativePath
     * @return string
     * @throws FileNotFoundException
     */
    public function getImageUrl(File $file, string $size, bool $relativePath = false): string
    {
        $storage = $this->getStorageFor($file);
        return $storage->getImageUrl($file, $size, $relativePath);
    }

    /**
     * Get the IRI to download this file (eg: /api/download/1)
     *
     * @param File $file
     * @return string
     */
    public function getDownloadIri(File $file): string
    {
        return $this->iriConverter->getIriFromResource(
            File::class,
            UrlGeneratorInterfaceApiPlatform::ABS_PATH,
            new Get(),
            ['fileId' => $file->getId()]
        );
    }
}
