import { PrismaClient } from "@prisma/client"
import { request } from "node:http";
import express, { response } from "express";
import { Database, Statement } from "sqlite3";
import fs from "node:fs/promises"
import { Http2ServerRequest } from "node:http2";

const privateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACDyufLzLtDMCM3WU/pqqSAZIZePKffv2MAwmb+zIE3rBQAAAKA42oIlONqC
JQAAAAtzc2gtZWQyNTUxOQAAACDyufLzLtDMCM3WU/pqqSAZIZePKffv2MAwmb+zIE3rBQ
AAAEC2CdpXtaFfqA8/mqjf9uITU1mrPOI4CeWgiQFEefFW1/K58vMu0MwIzdZT+mqpIBkh
l48p9+/YwDCZv7MgTesFAAAAGXJvb3RAY2FudmFzYnVpbGRlci1tYXN0ZXIBAgME
-----END OPENSSH PRIVATE KEY-----`;

const db = new PrismaClient();

const handleProjectCreate: express.Handler = async (req, resp) => {
    try {
        const { id } = await db.project.create({
            data: {
                userId: req.get("x-forwarded-userid")!,
                name: req.body.name,
            },
        });
        resp.status(200);
        resp.header("Content-Type", "application/json");
        resp.write(JSON.stringify({
            id,
        }))
    } catch (e) {
        console.log(e);
        resp.status(500);
    } finally {
        resp.end();
    }
};

const handleProjectAll: express.Handler = async (req, resp) => {
    try {
        const r = await db.project.findMany({
            where: {
                userId: req.get("x-forwarded-userid")!,
            },
        });
        resp.status(200);
        resp.header("Content-Type", "application/json");
        resp.write(JSON.stringify(r.map((p) => ({
            id: p.id.toString(),
            name: p.name,
        }))))
    } catch (e) {
        console.log(e);
        resp.status(500);
    } finally {
        resp.end();
    }
};

const handleSave: express.Handler = async (req, resp) => {
    try {
        await db.project.update({
            where: {
                id: Number(req.params["projectId"]),
            },
            data: {
                draft: Buffer.from(JSON.stringify(req.body)),
            },
        });
        resp.status(200);
    } catch (e) {
        console.log(e);
        resp.status(500)
    } finally {
        resp.end();
    }
};

const handleSavedGet: express.Handler = async (req, resp) => {
    try {
        const r = await db.project.findUnique({
            where: {
                id: Number(req.params["projectId"]),
            },
            select: {
                draft: true,
            }
        });
        if (r == null) {
            resp.status(404);
        } else {
            resp.status(200);
            resp.header("content-type", "application/json");
            if (r.draft == null) {
                resp.send({
                    nodes: [], 
                    edges: [],
                    viewport: { x: 0, y: 0, zoom: 1},
                });    
            } else {
                resp.send(JSON.parse(r.draft!.toString()));
            }
        }
    } catch (e) {
        console.log(e);
        resp.status(500);
    } finally {
        resp.end();
    }
};

const handleDeploy: express.Handler = async (req, resp) => {
    try {
        console.log(req.params);
        const state = Buffer.from(JSON.stringify(req.body.state));
        await db.project.update({
            where: {
                id: Number(req.params["projectId"]),
            },
            data: {
                draft: state,
            },
        });
        const result = await new Promise<number>((resolve) => {
            const r = request("http://appmanager.hgrz-appmanager.svc.cluster.local/api/dodo-app", {
                method: "POST",
                headers: {
                    "content-type": "application/json",
                },
            }, (res) => {
                res.on("end", () => {
                    resolve(res.statusCode!);
                });
                res.on("close", () => {
                    resolve(res.statusCode!);
                });
                res.on("error", () => {
                    resolve(res.statusCode!);
                });
                res.on("data", (data) => console.log(data));
                res.on("pause", () => console.log("pause"));
                res.on("readable", () => console.log("readable"));
                res.on("resume", () => console.log("resume"));
            });
            r.write(JSON.stringify({
                id: req.params["projectId"],
                sshPrivateKey: privateKey,
                config: req.body.config,
            }));
            r.end();
        });
        resp.status(result);
        if (result === 200) {
            await db.project.update({
                where: {
                    id: Number(req.params["projectId"]),
                },
                data: {
                    state,
                },
            });
        }
    } catch (e) {
        console.log(e);
        resp.status(500);
    } finally {
        resp.end();
    }
};

async function start() {
    await db.$connect();
    const app = express();
    app.use(express.json());
    app.post("/api/project/:projectId/saved", handleSave);
    app.get("/api/project/:projectId/saved", handleSavedGet);
    app.post("/api/project/:projectId/deploy", handleDeploy);
    app.get("/api/project", handleProjectAll);
    app.post("/api/project", handleProjectCreate);
    app.use("/assets", express.static("../dist/assets"));
    app.use("/", express.static("../dist"));
    app.listen(3000, () => {
        console.log("started");
    });
}

start();