import { ServerWebSocket } from "bun";
import {
    WebSocketData,
    WebSocketDataType,
    WebSocketMessageParam,
} from "../types";
import { EJSON } from "../exports/client-exports";
import socketClientPing from "./events/client-ping";
import debugLog from "@moduletrace/datasquirel/dist/package-shared/utils/logging/debug-log";
import socketClientServiceServerLogs from "./events/client-service-server-logs";
import socketClientKillPort from "./events/client-kill-port";
import socketClientServiceServerShell from "./events/client-service-server-shell";
import socketClientKillAllPorts from "./events/client-kill-all-ports";

type Param = {
    ws: ServerWebSocket<WebSocketData>;
    message: string | Buffer;
};

export default async function socketMessage({ ws, message }: Param) {
    const user = ws.data.user;
    const data = EJSON.parse(message.toString()) as
        | WebSocketDataType
        | undefined;

    const websocketMessageParams: WebSocketMessageParam = {
        ws,
        data,
        message,
    };

    const userRef = `User ${user.first_name} ${user.last_name} [#${user.id}]`;
    const label = "Web Socket Message";

    switch (data?.event) {
        case "client:ping":
            debugLog({
                log: `${userRef} Pinging Server ...`,
                addTime: true,
                label,
            });
            await socketClientPing(websocketMessageParams);
            break;
        case "client:service-server-logs":
            debugLog({
                log: `${userRef} Getting Service Server Logs ...`,
                addTime: true,
                label,
            });
            await socketClientServiceServerLogs(websocketMessageParams);
            break;
        case "client:service-server-shell":
            debugLog({
                log: `${userRef} Getting Service Server Shell ...`,
                addTime: true,
                label,
            });
            await socketClientServiceServerShell(websocketMessageParams);
            break;
        case "client:kill-port":
            debugLog({
                log: `${userRef} Killing Port ${data.port} ...`,
                addTime: true,
                label,
            });
            await socketClientKillPort(websocketMessageParams);
            break;
        case "client:kill-all-ports":
            debugLog({
                log: `${userRef} Killing All Ports ...`,
                addTime: true,
                label,
            });
            await socketClientKillAllPorts(websocketMessageParams);
            break;

        default:
            break;
    }
}
