const { VM } = require('vm2')
const { Server } = require('socket.io')
const util = require('util')
const { stylize } = require('./colors')
const randomstring = require('randomstring')
const ChatMessage = require('prismarine-chat')('1.20.1')

const BRIDGE_PREFIX = 'function:'

const io = new Server(3069)

function checkString (string) {
    if (typeof(string) !== 'string') throw new Error('Must be a string')
}

io.on('connection', (socket) => {
    let vm
    function resetVM () {
        vm = new VM({
            timeout: 3000,
            sandbox: {
                chat: (message) => {
                    checkString(message)
                    socket.emit(BRIDGE_PREFIX + 'chat', message)
                },
                core: (command) => {
                    checkString(command)
                    socket.emit(BRIDGE_PREFIX + 'core', command)
                },
                randomstring,
                ChatMessage
            }
        })
    }

    resetVM()

    socket.on('runCode', (transactionId, code) => {
        try {
            const output = vm.run(code)

            socket.emit('codeOutput', transactionId, false, util.inspect(output, { stylize }))
        } catch (e) {
            socket.emit('codeOutput', transactionId, true, e.toString())
        }
    })

    socket.on('reset', resetVM)
})