<?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 Psr\Log\LoggerInterface;

/**
 * Class which duplicate a stored object into a new one, recreating a stored object.
 */
class StoredObjectDuplicate
{
    public function __construct(private readonly StoredObjectManagerInterface $storedObjectManager, private readonly LoggerInterface $logger) {}

    public function duplicate(StoredObject|StoredObjectVersion $from, bool $onlyLastKeptBeforeConversionVersion = true): StoredObject
    {
        $storedObject = $from instanceof StoredObjectVersion ? $from->getStoredObject() : $from;

        $fromVersion = match ($storedObject->hasKeptBeforeConversionVersion() && $onlyLastKeptBeforeConversionVersion) {
            true => $from->getLastKeptBeforeConversionVersion(),
            false => $storedObject->getCurrentVersion(),
        };

        if (null === $fromVersion) {
            throw new \UnexpectedValueException('could not find a version to restore');
        }

        $oldContent = $this->storedObjectManager->read($fromVersion);

        $storedObject = new StoredObject();

        $newVersion = $this->storedObjectManager->write($storedObject, $oldContent, $fromVersion->getType());

        $newVersion->setCreatedFrom($fromVersion);

        $this->logger->info('[StoredObjectDuplicate] Duplicated stored object from a version of a previous stored object', [
            'from_stored_object_uuid' => $fromVersion->getStoredObject()->getUuid(),
            'to_stored_object_uuid' => $storedObject->getUuid(),
            'old_version_id' => $fromVersion->getId(),
            'old_version_version' => $fromVersion->getVersion(),
            'new_version_id' => $newVersion->getVersion(),
        ]);

        return $storedObject;
    }
}
