from fastapi import FastAPI, Request, WebSocket
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import docker
import asyncio
import pty
import os

app = FastAPI()
client = docker.from_env()

# Подключаем статические файлы
app.mount("/static", StaticFiles(directory="static"), name="static")

# Подключаем шаблоны
templates = Jinja2Templates(directory="templates")

# -----------------------------
# Главная страница
# -----------------------------
@app.get("/", response_class=HTMLResponse)
def index(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

# -----------------------------
# API: создать контейнер
# -----------------------------
@app.post("/node/create")
async def create_node(name: str = "node"):
    container = client.containers.run(
        "alpine:latest",
        command="/bin/sh",
        tty=True,
        stdin_open=True,
        detach=True,
        network_mode="none"
    )
    return {"id": container.id[:12], "name": name}

# -----------------------------
# WS: терминал контейнера
# -----------------------------
@app.websocket("/ws/{cid}")
async def ws_terminal(ws: WebSocket, cid: str):
    await ws.accept()
    container = client.containers.get(cid)
    pid = container.attrs["State"]["Pid"]
    master, slave = pty.openpty()
    tty = open(f"/proc/{pid}/root/dev/console", "rb+", buffering=0)

    async def read_from_container():
        while True:
            data = os.read(master, 1024)
            await ws.send_bytes(data)

    loop = asyncio.get_event_loop()
    loop.create_task(read_from_container())

    while True:
        msg = await ws.receive_text()
        os.write(master, msg.encode())
