# Written by retoor@molodetz.nl

# This code defines a web application for uploading and retrieving files. 
# It includes functionality to upload files through a POST request and retrieve them via a GET request. 

# The code uses the following non-standard imports: 
# - snek.system.view.BaseView: For extending view functionalities.
# - aiofiles: For asynchronous file operations.
# - aiohttp: For managing web server requests and responses.

# MIT License: This software is licensed under the MIT License, a permissive free software license.

from snek.system.view import BaseView
import aiofiles
import pathlib
from aiohttp import web
import uuid

UPLOAD_DIR = pathlib.Path("./drive")

class UploadView(BaseView):

    async def get(self):
        uid = self.request.match_info.get("uid")
        drive_item = await self.services.drive_item.get(uid)
        return web.FileResponse(drive_item["path"])

    async def post(self):
        reader = await self.request.multipart()
        files = []

        UPLOAD_DIR.mkdir(parents=True, exist_ok=True)

        channel_uid = None

        drive = await self.services.drive.get_or_create(user_uid=self.request.session.get("uid"))

        extension_types = {
            ".jpg": "image",
            ".gif": "image",
            ".png": "image",
            ".jpeg": "image",
            ".mp4": "video",
            ".mp3": "audio",
            ".pdf": "document",
            ".doc": "document",
            ".docx": "document"
        }

        while field := await reader.next():
            if field.name == "channel_uid":
                channel_uid = await field.text()
                continue

            filename = field.filename
            if not filename:
                continue

            file_path = pathlib.Path(UPLOAD_DIR).joinpath(filename.strip("/").strip("."))
            files.append(file_path)

            async with aiofiles.open(str(file_path.absolute()), 'wb') as f:
                while chunk := await field.read_chunk():
                    await f.write(chunk)

            drive_item = await self.services.drive_item.create(
                drive["uid"], filename, str(file_path.absolute()), file_path.stat().st_size, file_path.suffix
            )
           
            type_ = "unknown"
            extension = "." + filename.split(".")[-1]
            if extension in extension_types:
                type_ = extension_types[extension] 
            
            await self.services.drive_item.save(drive_item)
            response = "Uploaded [" + filename + "](/drive.bin/" + drive_item["uid"] + ")"
            #response = "<iframe width=\"100%\" frameborder=\"0\" allowfullscreen title=\"Embedded\" src=\"" + self.base_url + "/drive.bin/" + drive_item["uid"] + "\"></iframe>\n"
            response = "[url](/drive.bin/" + drive_item["uid"] + extension + ")"

            await self.services.chat.send(
                self.request.session.get("uid"), channel_uid, response
            )

        return web.json_response({"message": "Files uploaded successfully", "files": [str(file) for file in files], "channel_uid": channel_uid})
