<?php

namespace Internetgalerie\IgDatapoolFe\Utility;

use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
use TYPO3\CMS\Extbase\Service\ImageService;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use Internetgalerie\IgDatapoolFe\Services\IconService;
use Internetgalerie\IgDatapoolFe\Lib\FileUpload;
use Internetgalerie\IgDatapoolFe\Services\FormService;
use Internetgalerie\IgDatapoolFe\Event\FileUploadBeforeMoveToEvent;
use Internetgalerie\IgDatapoolFe\Property\TypeConverter\FileReferenceConverter;
use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Crypto\Random;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Resource\File as FileResource;
use TYPO3\CMS\Core\Resource\Security\FileNameValidator;
use TYPO3\CMS\Core\Resource\DuplicationBehavior;
use TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException;
use TYPO3\CMS\Core\Resource\Folder;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Page\AssetCollector;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\PathUtility;
use TYPO3\CMS\Core\Utility\StringUtility;
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
use TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Form\Mvc\Property\TypeConverter\UploadedFileReferenceConverter;

class FormUtility implements SingletonInterface
{
    protected $debug = false;
    protected $debugLog = '/tmp/log2.txt';

    protected $sizeLimit = null;

    protected $defaultUploadDir = 'fileadmin/_temp_/';

    /**
     * @var HashService
     */
    protected $hashService;

    /**
     * @var ImageService
     */
    protected $imageService;

    /**
     * @var ResourceFactory
     */
    protected $resourceFactory;

    /**
     * @var IconFactory
     */
    protected $iconFactory;

    /**
     * @var FormService
     */
    protected FormService $formService;

    /**
     * @param HashService $hashService
     */
    public function injectHashService(HashService $hashService): void
    {
        $this->hashService = $hashService;
    }

    /**
     * @param ImageService $imageService
     */
    public function injectImageService(ImageService $imageService): void
    {
        $this->imageService = $imageService;
    }

    /**
     * @param ResourceFactory $resourceFactory
     */
    public function injectResourceFactory(ResourceFactory $resourceFactory): void
    {
        $this->resourceFactory = $resourceFactory;
    }

    /**
     * @param IconFactory $iconFactory
     */
    public function injectIconFactory(IconFactory $iconFactory): void
    {
        $this->iconFactory = $iconFactory;
    }

    /**
     * @param FormService $formService
     */
    public function injectFormService(FormService $formService): void
    {
        $this->formService = $formService;
    }


    public function getSizeLimit()
    {
        return $this->sizeLimit;
    }
    public function setSizeLimit(int $sizeLimit): void
    {
        $this->sizeLimit = $sizeLimit;
    }

    public function prepareData($value)
    {
        $ret = [];
        global $TYPO3_CONF_VARS;
        $isImage = false;
        $image = null;
        $fileName = '';
        $fileSize = 0;
        $publicUrl = '';
        if ($value instanceof FileResource) {
            if (explode('/', $value->getMimeType())[0] == 'image') {
                $image = $value;
                $isImage = true;
            }
            $publicUrl = $value->getPublicUrl();
            $fileName = $value->getName();
            $fileSize = $value->getSize();
        } elseif ($value instanceof FileReference) {
            if (explode('/', $value->getOriginalResource()->getMimeType())[0] == 'image') {
                $image = $value;
                $isImage = true;
            }
            $publicUrl = $value->getOriginalResource()->getOriginalFile()->getPublicUrl();
            $fileName = $value->getOriginalResource()->getName();
            $fileSize = $value->getOriginalResource()->getSize();
        } elseif (is_array($value)) {
            $publicUrl = $this->defaultUploadDir . $value['curFile'];
            $extension = strtolower(pathinfo((string) $value['curFile'], PATHINFO_EXTENSION));
            if (in_array($extension, explode(',', (string) $TYPO3_CONF_VARS['GFX']['imagefile_ext'])) && $extension != 'pdf') {
                $image = $this->resourceFactory->retrieveFileOrFolderObject(GeneralUtility::getFileAbsFileName($publicUrl));
                $isImage = true;
            }
            $fileName = $value['origFilename'];
            $fileSize = $this->resourceFactory->retrieveFileOrFolderObject(GeneralUtility::getFileAbsFileName($publicUrl))->getSize();
        }
        $fileExt = pathinfo((string) $fileName, PATHINFO_EXTENSION);
        // is it an image?
        if ($image  !=  null) {
            if ($fileExt != 'svg') {
                $image = $this->imageService->getImage('', $image, true);
                $processingInstructions = ['maxWidth' => '320', 'maxHeight' => '320'];
                //$processingInstructions = array('maxWidth' => '100', 'maxHeight' => '50');
                $processedImage = $this->imageService->applyProcessingInstructions($image, $processingInstructions);
                $thumbUrl = $this->imageService->getImageUri($processedImage);
            } else {
                // File in einen ungeschuetzten Folder kopieren (svg Bild)
                if (strstr((string) $publicUrl, 'fileadmin/_temp_')) {
                    $fullPath = GeneralUtility::getFileAbsFileName($publicUrl);
                    //$fullPath=Environment::getPublicPath() .'/'. $publicUrl;
                    $fullPathProcessed = str_replace($this->defaultUploadDir, 'typo3temp/assets/_processed_/', $fullPath);
                    copy($fullPath, $fullPathProcessed);
                    $thumbUrl = '/' . ltrim($fullPathProcessed, '/'); //publicUrlProcessed ??
                } else {
                    $thumbUrl = '/' . ltrim((string) $publicUrl, '/');
                }
            }
        } else {
            // no thumb
            $thumbUrl = null;
        }
        if ($fileSize > 0) {
            $fileSizeFormatted = BytesUtility::formatBytes($fileSize, 0, '.', '\'');
        } else {
            $fileSizeFormatted = '0B';
        }

        return [
            'isImage' => $isImage,
            'fileSize' => $fileSize,
            'fileSizeFormatted' => $fileSizeFormatted,
            'thumbUrl' => $thumbUrl,
            'publicUrl' => $publicUrl,
            'fileName' => $fileName,
            'fileExt' => $fileExt,
        ];
    }

    public function renderFile($value, $index = null)
    {
        $data = $this->prepareData($value);
        $html = '';
        if ($data['isImage']) {
            //$html .= '<div class="dp-file-thumb"><img  src="' . $data['thumbUrl'] . '" alt="Thumbnail" style="max-height:80px;max-width:100px" height="50" width="80" title="Thumbnail" /></div>';
            $html .= '<div class="dp-file-thumb"><img  src="' . $data['thumbUrl'] . '" alt="Thumbnail"  title="Thumbnail" /></div>';
        } else {
            $extension = substr((string) $data['publicUrl'], strrpos((string) $data['publicUrl'], '.') + 1);
            $html .= '<div class="dp-file-thumb">' . $this->iconFactory->getIconForFileExtension($extension, Icon::SIZE_LARGE)->render() . '</div>';
        }
        $textFileSize = LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core:show_item.php.filesize');
        //$textFileSize = LocalizationUtility::translate('LLL:EXT:form/Resources/Private/Language/Database:formEditor.elements.FileUploadMixin.editor.validators.FileSize.label');
        //$textFileSize = LocalizationUtility::translate('LLL:EXT:indexed_search/Resources/Private/Language/locallang:field.fileSize');

        $html .= '
<div class="dp-file-name">
<span class="dp-filename file-' . $data['fileExt'] . '">' . ($data['publicUrl'] && 0 ? '<a href="/' . $data['publicUrl'] . '" target="_blank">' . $data['fileName'] . '</a>' : $data['fileName']) . '</span><br />
<span class="dp-filesize">' . $textFileSize . ': ' . $data['fileSizeFormatted'] . '</span>
<div class="dp-file-delete">
<a href="#" class="delete-file">' . IconService::getIcon('actions-edit-delete') . '</a>
</div>
</div>
';
        return '<div class="dp-file-list-item" data-index="' . ($index ?? '') . '">' . $html . '</div>';
    }

    /**
     * Handle a ajax upload of a file
     *
     * @param string $formName the name of the form field
     * @param string $uploadDir the upload folder for the file
     * @param array $allowedExtensions allowed file extensions
     * @param bool $useUniqueFilename use unique file name (add a secure hash to the file)
     * @return array the uploaded file
     */
    public function handleAjaxUpload($formName = 'uploadFile', $uploadDir = null, $allowedExtensions = null)
    {
        $uploader = GeneralUtility::makeInstance(FileUpload::class, $formName);

        if ($this->sizeLimit > 0) {
            $uploader->setSizeLimit($this->sizeLimit);
        }

        //$allowedExtensions = [ 'gif', 'png', 'jpeg', 'jpg' ];
        if ($uploadDir === null) {
            $uploadDir = GeneralUtility::getFileAbsFileName($this->defaultUploadDir);
        }
        $result = $uploader->handleUpload($uploadDir, $allowedExtensions);

        if (!$result) {
            //echo json_encode(array('success' => false, 'msg' => $Upload->getErrorMsg()));
            return ['status' => 'fail', 'msg' => $uploader->getErrorMsg()];
        } else {
            //echo json_encode(array('success' => true, 'file' => $Upload->getFileName()));
            $res = [];
            $arr = [];
            //$savedFileName=$uploader->getSavedFileName();
            //$originalFileName=$uploader->getOriginalFileName();
            $savedFileName = basename($uploader->getSavedFile());
            $originalFileName = $uploader->getFileName();

            $arr['curFile'] = $savedFileName;
            $arr['origFilename'] = $originalFileName;

            $formUtility = GeneralUtility::makeInstance(FormUtility::class);
            $res['msg'] = $formUtility->renderFile($arr);
            $res['status'] = 'ok';
            $res['value'] = $savedFileName;
            $res['originalName'] = $originalFileName;
            return $res;
        }
    }
    public function renderUploader($text = 'Datei hochladen...', $class = '')
    {
        return '<input type="button" value="' . $text . '" class="dp-button dp-file-newbutton ' . $class . '" />';
    }
    public function renderFileBrowser($name, $index, $fileBrowser, $options = null)
    {
        if (empty($fileBrowser) || !isset($fileBrowser['path'])) {
            return '';
        }
        $indexName = $index === null ? '' : '[' . $index . ']';
        $text = $fileBrowser['label'] ?? 'Datei auswählen...';
        $class = $fileBrowser['class'] ?? '';
        $folder = $this->resourceFactory->getFolderObjectFromCombinedIdentifier($fileBrowser['path']);
        $files = $folder->getFiles();
        $inputs = '';
        if (!empty($files)) {
            $inputOptions = '';
            foreach ($files as $file) {
                $inputOptions .= '<option value="' . $file->getUid() .'">' . $file->getName() . '</option>';
            }
            $inputs = '<input type="hidden" class="dpObject" name="' . $name . $indexName . '[__dpObject]" value="FileReference" data-attribute="[__dpObject]" />';
            $inputs .= '<select name="' . $name . $indexName  . '[uidLocal][newFileUid]"><option value=""></option>' . $inputOptions . '</select>';
            $inputs .= '<input type="hidden" name="' . $name . $indexName . '[uidLocal][options]" value="' . htmlspecialchars($this->hashService->appendHmac((string) base64_encode(serialize($options)))) . '" data-attribute="[uidLocal][options]" />';
        }
        return $inputs;
        //return $html . '<input type="button" value="' . $text . '" class="dp-button dp-file-browse ' . $class . '" data-config="' . htmlspecialchars(json_encode($fileBrowser)) . '" />';
    }
    public function addJsFooter(): void
    {
        GeneralUtility::makeInstance(AssetCollector::class)->addJavaScript(
            'ig_datapool_fe_upload',  // Unique key
            'EXT:ig_datapool_fe/Resources/Public/JavaScript/SimpleAjaxUploader.min.js',
            ['defer' => true] // Optional attributes
        );
    }
    
    public function renderFileReferenceInputFields($name, $index, $value, $options)
    {
        if ($value instanceof FileReference) {
            // these guys might be 0, if the row hasnt been stored yet!
            if ($value->getUid() != null) {
                $fileReference = $value;
            } else {
                $fileReference = $value->getOriginalResource();
                // @todo gibt es dies wirklich noch?????
            }
        } else {
            $fileReference = null;
        }
        $indexName = $index === null ? '' : '[' . $index . ']';
        $inputs = '';
        $inputs .= '<input type="hidden" class="dpObject" name="' . $name . $indexName . '[__dpObject]" value="FileReference" data-attribute="[__dpObject]" />';
        $inputs .= '<input type="hidden" class="newFile" name="' . $name . $indexName . '[uidLocal][newFile]" value="" data-attribute="[uidLocal][newFile]" />';
        $inputs .= '<input type="hidden" class="origFilename" name="' . $name . $indexName . '[uidLocal][origFilename]" value="" data-attribute="[uidLocal][origFilename]" />';

        if ($fileReference !== null) {
            if (method_exists($fileReference, 'getOriginalResource')) {
                $fileReferenceObject = $fileReference->getOriginalResource();
            } else {
                $fileReferenceObject = $fileReference;
            }
            $fileUid = $fileReferenceObject->getOriginalFile()->getUid();
            $inputs .= '<input type="hidden" class="curFile" name="' . $name . $indexName . '[uidLocal][curFile]" value="' . htmlspecialchars($this->hashService->appendHmac((string) $fileUid)) . '" data-attribute="[uidLocal][curFile]" />';
            $inputs .= '<input type="hidden" class="uid" name="' . $name . $indexName . '[__identity]" value="' . $fileReference->getUid() . '" data-attribute="[__identity]" />';
            //$inputs .= '<input type="hidden" class="uid" name="' . $name . $indexName . '[__identity]" value="' . htmlspecialchars($this->hashService->appendHmac((string) $fileReference->getUid() )) . '" />';
            $inputs .= '<input type="hidden" class="remove" name="' . $name . $indexName . '[uidLocal][remove]" value="0" data-attribute="[uidLocal][remove]" />';
            if ($this->debug) {
                $inputs .= $name . $indexName . ': uid=' . $fileReference->getUid() . ', fileUid=' . $fileUid;
            }
        }

        $inputs .= '<input type="hidden" name="' . $name . $indexName . '[uidLocal][options]" value="' . htmlspecialchars($this->hashService->appendHmac((string) base64_encode(serialize($options)))) . '" data-attribute="[uidLocal][options]" />';

        return '<div class="dp-file-hidden-field" data-index="' . $index . '" data-empty="' . ($value === null ? '1' : '0') . '">' . $inputs . '</div>';
    }

    public function renderFileInputFields($name, $value, $options)
    {
        $index = 0;
        //$indexName=$index===null ? '' : '[' . $index . ']';
        $inputs = '';
        //$inputs .= '<input type="hidden" class="mode" name="' . $name . '[mode]" value="' . htmlspecialchars($this->hashService->appendHmac('sys_file')) .'" />';
        $inputs .= '<input type="hidden" class="dpObject" name="' . $name . '[__dpObject]" value="File" data-attribute="[__dpObject]" />';
        $inputs .= '<input type="hidden" class="newFile" name="' . $name . '[newFile]" value="" data-attribute="[newFile]" />';
        $inputs .= '<input type="hidden" class="origFilename" name="' . $name . '[origFilename]" value="" data-attribute="[origFilename]" />';

        if ($value instanceof FileResource) {
            $fileUid = $value->getUid();
            //$fileUid = $value->getOriginalFile()->getUid(); // wenn Model
            $inputs .= '<input type="hidden" class="curFile" name="' . $name . '[curFile]" value="' . htmlspecialchars($this->hashService->appendHmac((string) $fileUid)) . '" data-attribute="[curFile]" />';
            //$inputs .= '<input type="hidden" class="uid" name="' . $name . '[__identity]" value="' .  $value->getUid() . '" data-attribute="[__identity]" />';
            //$inputs .= '<input type="hidden" class="fileUid" name="' . $name . '[fileUid]" value="' . htmlspecialchars($this->hashService->appendHmac((string) $fileUid)) . '" data-attribute="[fileUid]" />';
            $inputs .= '<input type="hidden" class="remove" name="' . $name . '[remove]" value="0" data-attribute="[remove]" />';
        }
        $inputs .= '<input type="hidden" name="' . $name . '[options]" value="' . htmlspecialchars($this->hashService->appendHmac((string) base64_encode(serialize($options)))) . '" data-attribute="[options]" />';

        return '<div class="dp-file-hidden-field" data-index="' . $index . '" data-empty="' . ($value === null ? '1' : '0') . '">' . $inputs . '</div>';
    }

    public function updateFileReference()
    {
    }
    public function retrieveFileOrFolderObject(string $filePath)
    {
        return $this->resourceFactory->retrieveFileOrFolderObject($filePath);
    }

    public function createFileReferenceFromFile($file)
    {
        return $this->resourceFactory->getFileReferenceObject($file);
    }

    public function createFileReference($newFile, $origFilename, $options, ?PropertyMappingConfigurationInterface $configuration = null)
    {
        // it is atemporary string
        $filePath = Environment::getPublicPath() . '/' . $this->defaultUploadDir . $newFile;
        if ($this->debug) {
            $this->log('test ' . $filePath);
        }
        // if there was a problem and our source file doesn't exist, we just return NULL
        if (!is_file($filePath)) {
            return null;
        }

        // check again for php and illegal stuff
        if (!GeneralUtility::makeInstance(FileNameValidator::class)->isValid($newFile)) {
            throw new TypeConverterException('Uploading files with PHP file extensions is not allowed!', 1399312430);
        }
        // get the uploaded file object
        $uploadedFile = $this->resourceFactory->retrieveFileOrFolderObject($filePath);
        if ($this->debug) {
            $this->log('uploadedFile');
        }
        // do the checks here VALIDATION
        if (isset($options['maxSize'])) {
            $size = $uploadedFile->getSize();
            if ($size > $options['maxSize'] * 1024) {
                $uploadedFile->delete();
                return 'validator.file.tooBig';
            }
        }

        if (isset($options['allowedExtensions']) && $options['allowedExtensions'] != '*') {
            $ext = $uploadedFile->getExtension();
            if (!in_array($ext, $options['allowedExtensions'])) {
                $uploadedFile->delete();
                return 'validator.file.invalidType';
            }
        }

        if (isset($options['minImageSize'])) {
            $minSize = $options['minImageSize'];
            if (stripos((string) $minSize, 'mp')) {
                $minSize = floatval($minSize) * (1024 * 1024);
            } else {
                $minSize = floatval($minSize);
            }

            $size = getimagesize($uploadedFile->getForLocalProcessing(false));

            $fullSize = $size[0] * $size[1];
            if ($fullSize > 0 && $fullSize < $minSize) {
                $uploadedFile->delete();
                return 'validator.image.tooSmall';
            }
        }

        // create upload folder

        //$uploadFolder = $this->resourceFactory->retrieveFileOrFolderObject('1:/');
        /*
        $request = $formService->getController()->getRequest();

        // move to fileadmin/datapool_upload/extension/controller/origFilename.jpg
        if ($options['folder']) {
        if (substr($options['folder'], 0, 1)=='/') {
        $folderName = substr($options['folder'], 1);
        } else {
        $folderName = 'datapool_upload/' . $request->getControllerExtensionName() . '/' . $request->getControllerName()  . '/' . $options['folder'];
        }
        } else {
        $folderName = 'datapool_upload/' . $request->getControllerExtensionName() . '/' . $request->getControllerName();
        }

        if (!$uploadFolder->hasFolder($folderName)) {
        $uploadFolder = $uploadFolder->createFolder($folderName);
        } else {
        $uploadFolder = $uploadFolder->getSubfolder($folderName);
        }
         */
        // rename and move
        //$uploadedFile = $uploadedFile->rename($origFilename)->moveTo($uploadFolder, NULL, \TYPO3\CMS\Core\Resource\DuplicationBehavior::RENAME);
        $eventDispatcher = GeneralUtility::makeInstance(EventDispatcherInterface::class);
        $fileUploadBeforeMoveToEvent = $eventDispatcher->dispatch(
            new FileUploadBeforeMoveToEvent($options['folder'], $origFilename, DuplicationBehavior::RENAME)
        );
        $uploadFolderPath = $fileUploadBeforeMoveToEvent->getUploadFolder();
        $origFilename = $fileUploadBeforeMoveToEvent->getFileName();
        $conflictMode = $fileUploadBeforeMoveToEvent->getConflictMode();

        $subFolder = null;
        if ($configuration) {
            $seed = $configuration->getConfigurationValue(
                FileReferenceConverter::class,
                UploadedFileReferenceConverter::CONFIGURATION_UPLOAD_SEED
            ) ?: GeneralUtility::makeInstance(Random::class)->generateRandomHexString(40);
            $currentName = 'form_' . GeneralUtility::hmac($seed, self::class);
            $uploadFolderId = $configuration->getConfigurationValue(FileReferenceConverter::class, UploadedFileReferenceConverter::CONFIGURATION_UPLOAD_FOLDER);

            if ($uploadFolderId) {
                $uploadFolder = $this->provideUploadFolder($uploadFolderId);
                // current folder name, derived from public random seed (`formSession`)
                $currentName = 'form_' . GeneralUtility::hmac($seed, self::class);
                $subFolder = $this->provideTargetFolder($uploadFolder, $currentName);
            }
        }
        // sub-folder in $uploadFolder with 160 bit of derived entropy (.../form_<40-chars-hash>/actual.file)
        $uploadFolder = $this->formService->getUploadFolder($options['folder'], $subFolder ? $subFolder->getReadablePath() : null);
        $origFilename = FileUpload::sanitizeFilename($origFilename);
        //var_dump($origFilename,$options['folder'],$uploadFolder);exit(0);
        //var_dump(GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Resource\FilePathSanitizer::class)->sanitize($origFilename));

        $uploadedFile = $uploadedFile->moveTo($uploadFolder, $origFilename, $conflictMode);

        if ($this->debug) {
            $this->log('call:' . $uploadedFile::class);
        }
        $fileReference = $this->createFileReferenceFromFileResourceObject($uploadedFile);
        return $fileReference;
        //store it for later use..
    }

    /**
     * @param  FileResource $file
     * @return FileReference
     */
    public function createFileReferenceFromFileResourceObject(FileResource $file)
    {
        if ($this->debug) {
            $this->log('createFileReferenceFromFileResourceObject(FileResource)');
            $this->log('fileUid=' . $file->getUid() . ',' . $file->getPublicUrl());
        }
        //$fileReference = $this->resourceFactory->createFileReferenceObject(array('uid_local' => $file->getUid(), 'uid_foreign' => uniqid('NEW_'), 'uid' => uniqid('NEW_'), ));
        /*
        $className = \MyVendor\MyExt\Domain\Model\SomeModel::class;
        $dataMapper = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class);
        $tableName = $dataMapper->getDataMap($className)->getTableName();
        GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\FileReference::class, [
         */

        $fileReferenceResource = $this->resourceFactory->createFileReferenceObject(
            [
                'uid_local' => $file->getUid(),
                'uid_foreign' => StringUtility::getUniqueId('NEW_'),
                'uid' => StringUtility::getUniqueId('NEW_'),
                'crop' => null,
            ]
        ); //  'table_local' => 'sys_file', 'tablenames' => 'tx_tripsfinder_domain_model_trip',
        //$this->resourceFactory->getFileReferenceObject(array('uid_local' => $file->getUid(), 'uid_foreign' => uniqid('NEW_'), 'uid' => uniqid('NEW_'), ));
        return $this->createFileReferenceModelFromResource($fileReferenceResource); //Reference);
    }

    public function createFileReferenceFromFalUid($fileUid)
    {
        if ($this->debug) {
            $this->log('createFileReferenceFromFalUid:' . $fileUid);
        }
        //return $this->fileFactory->getFileReferenceObject( $fileUid, ['uid_foreign' => uniqid('NEW_')] );

        $fileReferenceResource = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\FileReference::class, ['uid_local' => $fileUid, 'uid_foreign' => uniqid('NEW_')]); //  'table_local' => 'sys_file', 'tablenames' => 'tx_tripsfinder_domain_model_trip',
        return $this->createFileReferenceModelFromResource($fileReferenceResource);
    }

    /**
     * Convert a FileReference Resource tp a FileReference Model
     *
     * @param  \TYPO3\CMS\Core\Resource\FileReference $fileReference
     * @return FileReference
     */
    public function createFileReferenceModelFromResource(\TYPO3\CMS\Core\Resource\FileReference $fileReferenceResource)
    {
        $fileReference = GeneralUtility::makeInstance(FileReference::class);
        $fileReference->setOriginalResource($fileReferenceResource);
        return $fileReference;
    }

    public function log($text): void
    {
        $fp = fopen($this->debugLog, 'a');
        fputs($fp, $text . "\n");
        fclose($fp);
    }
    public function log_var_dump($var): void
    {
        $fp = fopen($this->debugLog, 'a');
        //ob_start();      var_dump($var);      $text = ob_get_clean();
        $text = var_export($var, true);
        fputs($fp, 'File-DUMP[FileReferenceConverter]=' . $text . "\n");
        fclose($fp);
    }

    /**
     * Ensures that upload folder exists, creates it if it does not.
     *
     * @param string $uploadFolderIdentifier
     * @return Folder
     */
    protected function provideUploadFolder(string $uploadFolderIdentifier): Folder
    {
        try {
            return $this->resourceFactory->getFolderObjectFromCombinedIdentifier($uploadFolderIdentifier);
        } catch (FolderDoesNotExistException) {
            [$storageId, $storagePath] = explode(':', $uploadFolderIdentifier, 2);
            $storage = $this->resourceFactory->getStorageObject($storageId);
            $folderNames = GeneralUtility::trimExplode('/', $storagePath, true);
            $uploadFolder = $this->provideTargetFolder($storage->getRootLevelFolder(), ...$folderNames);
            $this->provideFolderInitialization($uploadFolder);
            return $uploadFolder;
        }
    }

    /**
     * Ensures that particular target folder exists, creates it if it does not.
     *
     * @param Folder $parentFolder
     * @param string $folderName
     * @return Folder
     */
    protected function provideTargetFolder(Folder $parentFolder, string $folderName): Folder
    {
        return $parentFolder->hasFolder($folderName)
            ? $parentFolder->getSubfolder($folderName)
            : $parentFolder->createFolder($folderName);
    }

    /**
     * Creates empty index.html file to avoid directory indexing,
     * in case it does not exist yet.
     *
     * @param Folder $parentFolder
     */
    protected function provideFolderInitialization(Folder $parentFolder): void
    {
        if (!$parentFolder->hasFile('index.html')) {
            $parentFolder->createFile('index.html');
        }
    }
}
