////
// The shell runs on the server and processes input, returning output.

import type { Message, CommandResult, CommandOutput } from "../shared/types.js"
import { addInput, setStatus, addOutput, appendOutput, replaceOutput } from "./scrollback.js"
import { send } from "./websocket.js"
import { randomId } from "../shared/utils.js"
import { addToHistory } from "./history.js"
import { browserCommands, cacheCommands } from "./commands.js"
import { handleGameStart } from "./game.js"

export function runCommand(input: string) {
    if (!input.trim()) return

    if (input.includes(";")) {
        input.split(";").forEach(cmd => runCommand(cmd.trim()))
        return
    }

    const id = randomId()

    addToHistory(input)
    addInput(id, input)

    const [cmd = "", ..._args] = input.split(" ")

    if (browserCommands[cmd]) {
        const result = browserCommands[cmd]()
        if (typeof result === "string")
            addOutput(id, result)
        setStatus(id, "ok")
    } else {
        send({ id, type: "input", data: input })
    }
}

// message received from server
export async function handleMessage(msg: Message) {
    switch (msg.type) {
        case "output":
            handleOutput(msg); break
        case "commands":
            cacheCommands(msg.data as string[]); break
        case "error":
            console.error(msg.data); break
        case "stream:start":
            handleStreamStart(msg); break
        case "stream:end":
            handleStreamEnd(msg); break
        case "stream:append":
            handleStreamAppend(msg); break
        case "stream:replace":
            handleStreamReplace(msg); break
        case "game:start":
            await handleGameStart(msg); break
        default:
            console.error("unknown message type", msg)
    }
}

function handleOutput(msg: Message) {
    const result = msg.data as CommandResult
    setStatus(msg.id!, result.status)
    addOutput(msg.id!, result.output)
}

function handleStreamStart(msg: Message) {
    const id = msg.id!

    const status = document.querySelector(`[data-id="${id}"].input .status`)
    if (!status) return

    addOutput(id, msg.data as CommandOutput)

    status.classList.remove("yellow")
    status.classList.add("purple")
}

function handleStreamAppend(msg: Message) {
    appendOutput(msg.id!, msg.data as CommandOutput)
}

function handleStreamReplace(msg: Message) {
    replaceOutput(msg.id!, msg.data as CommandOutput)
}

function handleStreamEnd(_msg: Message) {
}

