<?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\WopiBundle\Controller;

use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
use Chill\WopiBundle\Service\WopiConverter;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Security\Core\Security;

class ConvertController
{
    private const LOG_PREFIX = '[convert] ';

    public function __construct(
        private readonly Security $security,
        private readonly StoredObjectManagerInterface $storedObjectManager,
        private readonly WopiConverter $wopiConverter,
        private readonly LoggerInterface $logger,
    ) {}

    public function __invoke(StoredObject $storedObject, Request $request): Response
    {
        if (!($this->security->isGranted('ROLE_USER') || $this->security->isGranted('ROLE_ADMIN'))) {
            throw new AccessDeniedHttpException('User must be authenticated');
        }

        if (!$this->security->isGranted(StoredObjectRoleEnum::SEE->value, $storedObject)) {
            throw new AccessDeniedHttpException('not allowed to see this document');
        }

        $content = $this->storedObjectManager->read($storedObject);

        if ('application/pdf' === $storedObject->getType()) {
            return new Response($content, Response::HTTP_OK, ['Content-Type' => 'application/pdf']);
        }

        $lang = $request->getLocale();

        try {
            return new Response($this->wopiConverter->convert($lang, $content, $storedObject->getType()), Response::HTTP_OK, [
                'Content-Type' => 'application/pdf',
            ]);
        } catch (\RuntimeException $exception) {
            $this->logger->alert(self::LOG_PREFIX.'Could not convert document', ['message' => $exception->getMessage(), 'exception', $exception->getTraceAsString()]);

            return new Response('convert server not available', Response::HTTP_SERVICE_UNAVAILABLE);
        }
    }
}
