import pathlib

import aiohttp

from snek.system.terminal import TerminalSession
from snek.system.view import BaseView


class TerminalSocketView(BaseView):

    login_required = True

    user_sessions = {}

    async def prepare_drive(self):
        user = await self.services.user.get(uid=self.session.get("uid"))
        root = pathlib.Path("drive").joinpath(user["uid"])
        root.mkdir(parents=True, exist_ok=True)
        terminal_folder = pathlib.Path("terminal")
        for path in terminal_folder.iterdir():
            destination_path = root.joinpath(path.name)
            if not path.is_dir():
                destination_path.write_bytes(path.read_bytes())
        return root

    async def get(self):

        ws = aiohttp.web.WebSocketResponse()
        await ws.prepare(self.request)
        user = await self.services.user.get(uid=self.session.get("uid"))
        root = await self.prepare_drive()

        command = f"docker run -v ./{root}/:/root -it --memory 512M --cpus=0.5 -w /root snek_ubuntu /bin/bash"

        session = self.user_sessions.get(user["uid"])
        if not session:
            self.user_sessions[user["uid"]] = TerminalSession(command=command)
        session = self.user_sessions[user["uid"]]
        await session.add_websocket(ws)
        # asyncio.create_task(session.read_output(ws))

        async for msg in ws:
            if msg.type == aiohttp.WSMsgType.BINARY:
                await session.write_input(msg.data.decode())

        return ws


class TerminalView(BaseView):

    login_required = True

    async def get(self):
        return await self.request.app.render_template("terminal.html", self.request)
