// @ts-check

import http from "http";
import fs from "fs";
import path from "path";
import { exec, execSync, execFile, spawn, spawnSync } from "child_process";
import { createHmac } from "crypto";

require("dotenv").config({
    path: path.resolve(__dirname, ".env"),
});

declare global {
    var NODE_ENVIRONMENT: any;
}

const server = http.createServer();

const key = process.env.DSQL_GITHUB_SECRET;

let environment = process.env.NODE_ENVIRONMENT;

global.NODE_ENVIRONMENT = environment;

const PORT = process.env.DSQL_PORT;

const workingDirectory = path.resolve(__dirname, "../");

console.log(workingDirectory);

let child = spawn("node", ["./server.js"], {
    cwd: workingDirectory,
    stdio: "inherit",
    env: environment?.match(/prod/i) ? { NODE_ENV: "production" } : undefined,
});

child.on("exit", () => {
    console.log("Child Process Exited");
});

server.on("request", (req, res) => {
    /** ********************* Handle response Headers */
    if (!req.method?.match(/post/i)) {
        return res.writeHead(401, "Unauthorized").end();
    }

    let data = "";

    try {
        req.on("data", (chunk) => {
            data += chunk;
        });

        req.on("end", () => {
            console.log("Request Recieved");

            let parsedData = (() => {
                try {
                    return JSON.parse(data.toString());
                } catch (error: any) {
                    console.log(error.message);
                    return data.toString();
                }
            })();

            console.log("Request Received", parsedData);

            if (req.url == process.env.ENDPOINT) {
                const options: import("child_process").SpawnSyncOptionsWithBufferEncoding =
                    {
                        cwd: workingDirectory,
                        stdio: "inherit",
                    };

                if (process.platform?.match(/win/i)) {
                    options.shell = "bash.exe";
                }

                if (environment?.match(/prod/i)) {
                    spawnSync("git", ["checkout", "."], options);
                    spawnSync("git", ["pull"], options);
                    spawnSync("bun", ["install"], options);
                    spawnSync("bun", ["run", "build"], options);

                    child.kill();

                    child = spawn("node", ["./server.js"], {
                        cwd: workingDirectory,
                        stdio: "inherit",
                        env: { NODE_ENV: "production" },
                    });
                } else {
                    spawnSync("git", ["status"], options);
                    spawnSync("bun", ["list", "next"], options);

                    console.log("Not in production, Continuing ...");
                }

                res.statusCode = 200;
                res.end("Success");
            } else {
                res.statusCode = 400;
                res.end("Failed");
            }
        });
    } catch (error) {
        console.log(error);
        res.end(
            JSON.stringify({
                msg: "Not Handled Yet",
            })
        );
    }
});

server.listen(PORT, () => {
    console.log(`Listening on PORT ${PORT} => env: ${environment}`);
});
