<?php

namespace AppBundle\Service;

use AppBundle\Entity;
use AppBundle\Repository\FileRepository;
use Doctrine\DBAL\Connection;
use Symfony\Component\HttpFoundation\File\File as HttpFoundationFile;

class FileUploader
{
    /**
     * @var FileNameGenerator
     */
    private $fileNameGenerator;

    /**
     * @var Connection
     */
    private $connection;

    /**
     * @var FileRepository
     */
    private $fileRepository;

    /**
     * @var string
     */
    private $uploadDirectory;

    /**
     * @param string $uploadDirectory
     * @param FileNameGenerator $fileNameGenerator
     * @param FileRepository $fileRepository
     * @param Connection $connection
     */
    public function __construct(
        $uploadDirectory,
        FileNameGenerator $fileNameGenerator,
        FileRepository $fileRepository,
        Connection $connection
    ) {
        $this->uploadDirectory = $uploadDirectory;
        $this->fileNameGenerator = $fileNameGenerator;
        $this->connection = $connection;
        $this->fileRepository = $fileRepository;
    }

    /**
     * @param HttpFoundationFile $httpFoundationFile
     * @param string $clientOriginalName
     * @return Entity\File
     */
    public function upload(HttpFoundationFile $httpFoundationFile, $clientOriginalName)
    {
        $saveAs = $this->fileNameGenerator->generatePath($httpFoundationFile);
        $file = Entity\File::create($httpFoundationFile, $clientOriginalName, $saveAs);

        $saveFileInTransaction = function () use ($httpFoundationFile, $file, $saveAs) {
            $httpFoundationFile->move($this->uploadDirectory, $saveAs);
            $this->fileRepository->add($file);
        };

        $this->connection->transactional($saveFileInTransaction);

        return $file;
    }
}