import asyncio
import logging
from pathlib import Path
from typing import Callable

from gateway_core.application.ports.FileSystemPort import FileSystemPort
from gateway_core.application.ports.NotificationPort import NotificationPort
from gateway_core.application.ports.UploadPort import UploadPort
from gateway_core.domain.FileSystemData import FileUploadDto

logger = logging.getLogger(__name__)

class FileUploadUseCase:
    """
    This class should implement the business logic fo file handling.

    Maybe needs an Adapter for specific file sistem or how to access?
    """

    def __init__(
        self,
        fileSystem: FileSystemPort,
        uploadAdapter: UploadPort,
        notifyHandler: Callable,
    ) -> None:
        self._fileSystem = fileSystem
        self._uploadAdapter = uploadAdapter
        self._notifyHandler = notifyHandler


    async def execute(self, fileUploadDto: FileUploadDto):
        path = fileUploadDto.path
        if path.is_file():
            filePath = path
            fileSize = await self._fileSystem.getFileSize(path)
        elif path.is_dir():
            filePath = await self._fileSystem.createZip(path)
            fileSize = await self._fileSystem.getFileSize(Path(filePath))
        else:
            logger.warning(f"Path {path} is not a file or directory. Can not be Uploaded!")
            return


        with self._fileSystem.getFile(filePath) as file:
            await asyncio.gather(*[self._uploadAdapter.uploadFile(file, fileSize, fileUploadDto.uploadUrl),
                                   self._notifyHandler(fileUploadDto.taskId, self._uploadAdapter.getCurrentUploadStatus)])

        self._uploadAdapter.resetUploadStatus()

        if path.is_dir():
            self._fileSystem.deleteFile(Path(filePath))
