<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\DocStoreBundle\Service;

use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Entity\StoredObjectVersion;
use Chill\DocStoreBundle\Exception\StoredObjectManagerException;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

interface StoredObjectManagerInterface
{
    public const ALGORITHM = 'AES-256-CBC';

    /**
     * @param StoredObject|StoredObjectVersion $document if a StoredObject is given, the last version will be used
     */
    public function getLastModified(StoredObject|StoredObjectVersion $document): \DateTimeInterface;

    /**
     * @param StoredObject|StoredObjectVersion $document if a StoredObject is given, the last version will be used
     */
    public function getContentLength(StoredObject|StoredObjectVersion $document): int;

    /**
     * @throws TransportExceptionInterface
     */
    public function exists(StoredObject|StoredObjectVersion $document): bool;

    /**
     * Get the content of a StoredObject.
     *
     * @param StoredObject|StoredObjectVersion $document if a StoredObject is given, the last version will be used
     *
     * @return string the retrieved content in clear
     *
     * @throws StoredObjectManagerException if unable to read or decrypt the content
     */
    public function read(StoredObject|StoredObjectVersion $document): string;

    /**
     * Register the content of a new version for the StoredObject.
     *
     * The manager is also responsible for registering a version in the StoredObject, and return this version.
     *
     * @param StoredObject $document     the document
     * @param string       $clearContent The content to store in clear
     * @param string|null  $contentType  The new content type. If set to null, the content-type is supposed not to change. If there is no content type, an empty string will be used.
     *
     * @return StoredObjectVersion the newly created @see{StoredObjectVersion} for the given @see{StoredObject}
     *
     * @throws StoredObjectManagerException
     */
    public function write(StoredObject $document, string $clearContent, ?string $contentType = null): StoredObjectVersion;

    /**
     * Remove a version from the storage.
     *
     * This method is also responsible for removing the version from the StoredObject (using @see{StoredObject::removeVersion})
     * in case of success.
     *
     * @throws StoredObjectManagerException
     */
    public function delete(StoredObjectVersion $storedObjectVersion): void;

    /**
     * return or compute the etag for the document.
     *
     * @param StoredObject|StoredObjectVersion $document if a StoredObject is given, the last version will be used
     *
     * @return string the etag of this document
     */
    public function etag(StoredObject|StoredObjectVersion $document): string;

    /**
     * Clears the cache for the stored object.
     */
    public function clearCache(): void;
}
