import {
    NSQLITE_TURBOCI_ADMIN_USERS_PORTS,
    NSQLiteTables,
} from "@/src/db/types";
import { TtydInfoObject, TtydParams, User } from "@/src/types";
import getNextAvailablePort from "@/src/utils/grab-next-available-port";
import grabTtydCmd from "@/src/utils/grab-ttyd-cmd";
import grabConnectedWebsocketUserdata from "@/src/websocket/(utils)/grab-connected-websocket-user-data";
import BunSQLite from "@moduletrace/bun-sqlite";
import { exec } from "child_process";

type Params = {
    user: User;
    cmd: string;
    ttyd_options?: Omit<TtydParams, "cmd" | "port">;
};

export default async function grabTtydInfo({
    user,
    cmd,
    ttyd_options,
}: Params): Promise<TtydInfoObject> {
    const available_port = await getNextAvailablePort();

    let url = `/ttyd/${available_port}`;

    const ttyd_cmd = grabTtydCmd({
        cmd,
        port: available_port,
        ...ttyd_options,
    });

    const ttyd_exec = exec(ttyd_cmd.cmd);

    await Bun.sleep(2000);

    const connected_user_data = grabConnectedWebsocketUserdata({ user });

    await BunSQLite.insert<
        NSQLITE_TURBOCI_ADMIN_USERS_PORTS,
        (typeof NSQLiteTables)[number]
    >({
        data: [{ user_id: user.id, port: available_port }],
        table: "users_ports",
    });

    connected_user_data.child_processes.push(ttyd_exec);
    connected_user_data.ports.push(available_port);

    return { port: available_port, url };
}
