<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="author" content="Katie Bell">
    <meta name="description" content="Simple REPL for Python WASM">
    <title>wasm-python terminal</title>
    <link rel="stylesheet" href="https://unpkg.com/xterm@4.18.0/css/xterm.css" crossorigin integrity="sha384-4eEEn/eZgVHkElpKAzzPx/Kow/dTSgFk1BNe+uHdjHa+NkZJDh5Vqkq31+y7Eycd"/>
    <style>
        body {
            font-family: arial;
            max-width: 800px;
            margin: 0 auto
        }
        #code {
            width: 100%;
            height: 180px;
        }
        #info {
            padding-top: 20px;
        }
        .button-container {
            display: flex;
            justify-content: end;
            height: 50px;
            align-items: center;
            gap: 10px;
        }
        button {
            padding: 6px 18px;
        }
    </style>
    <script src="https://unpkg.com/xterm@4.18.0/lib/xterm.js" crossorigin integrity="sha384-yYdNmem1ioP5Onm7RpXutin5A8TimLheLNQ6tnMi01/ZpxXdAwIm2t4fJMx1Djs+"/></script>
    <script type="module">
class WorkerManager {
    constructor(workerURL, standardIO, readyCallBack, finishedCallback) {
        this.workerURL = workerURL
        this.worker = null
        this.standardIO = standardIO
        this.readyCallBack = readyCallBack
        this.finishedCallback = finishedCallback

        this.initialiseWorker()
    }

    async initialiseWorker() {
        if (!this.worker) {
            this.worker = new Worker(this.workerURL)
            this.worker.addEventListener('message', this.handleMessageFromWorker)
        }
    }

    async run(options) {
        this.worker.postMessage({
            type: 'run',
            args: options.args || [],
            files: options.files || {}
        })
    }

    reset() {
        if (this.worker) {
            this.worker.terminate()
            this.worker = null
        }
        this.standardIO.message('Worker process terminated.')
        this.initialiseWorker()
    }

    handleStdinData(inputValue) {
        if (this.stdinbuffer && this.stdinbufferInt) {
            let startingIndex = 1
            if (this.stdinbufferInt[0] > 0) {
                startingIndex = this.stdinbufferInt[0]
            }
            const data = new TextEncoder().encode(inputValue)
            data.forEach((value, index) => {
                this.stdinbufferInt[startingIndex + index] = value
            })

            this.stdinbufferInt[0] = startingIndex + data.length - 1
            Atomics.notify(this.stdinbufferInt, 0, 1)
        }
    }

    handleMessageFromWorker = (event) => {
        const type = event.data.type
        if (type === 'ready') {
            this.readyCallBack()
        } else if (type === 'stdout') {
            this.standardIO.stdout(event.data.stdout)
        } else if (type === 'stderr') {
            this.standardIO.stderr(event.data.stderr)
        } else if (type === 'stdin') {
            // Leave it to the terminal to decide whether to chunk it into lines
            // or send characters depending on the use case.
            this.stdinbuffer = event.data.buffer
            this.stdinbufferInt = new Int32Array(this.stdinbuffer)
            this.standardIO.stdin().then((inputValue) => {
                this.handleStdinData(inputValue)
            })
        } else if (type === 'finished') {
            this.standardIO.message(`Exited with status: ${event.data.returnCode}`)
            this.finishedCallback()
        }
    }
}

class WasmTerminal {

    constructor() {
        this.inputBuffer = new BufferQueue();
        this.input = ''
        this.resolveInput = null
        this.activeInput = false
        this.inputStartCursor = null

        this.xterm = new Terminal(
            { scrollback: 10000, fontSize: 14, theme: { background: '#1a1c1f' }, cols: 100}
        );

        this.xterm.onKey((keyEvent) => {
            // Fix for iOS Keyboard Jumping on space
            if (keyEvent.key === " ") {
                keyEvent.domEvent.preventDefault();
            }
        });

        this.xterm.onData(this.handleTermData)
    }

    open(container) {
        this.xterm.open(container);
    }

    handleTermData = (data) => {
        const ord = data.charCodeAt(0);
        data = data.replace(/\r(?!\n)/g, "\n")  // Convert lone CRs to LF

        // Handle pasted data
        if (data.length > 1 && data.includes("\n")) {
            let alreadyWrittenChars = 0;
            // If line already had data on it, merge pasted data with it
            if (this.input != '') {
                this.inputBuffer.addData(this.input);
                alreadyWrittenChars = this.input.length;
                this.input = '';
            }
            this.inputBuffer.addData(data);
            // If input is active, write the first line
            if (this.activeInput) {
                let line = this.inputBuffer.nextLine();
                this.writeLine(line.slice(alreadyWrittenChars));
                this.resolveInput(line);
                this.activeInput = false;
            }
        // When input isn't active, add to line buffer
        } else if (!this.activeInput) {
            // Skip non-printable characters
            if (!(ord === 0x1b || ord == 0x7f || ord < 32)) {
                this.inputBuffer.addData(data);
            }
        // TODO: Handle ANSI escape sequences
        } else if (ord === 0x1b) {
        // Handle special characters
        } else if (ord < 32 || ord === 0x7f) {
            switch (data) {
                case "\x0c": // CTRL+L
                    this.clear();
                    break;
                case "\n": // ENTER
                case "\x0a": // CTRL+J
                case "\x0d": // CTRL+M
                    this.resolveInput(this.input + this.writeLine('\n'));
                    this.input = '';
                    this.activeInput = false;
                    break;
                case "\x7F": // BACKSPACE
                case "\x08": // CTRL+H
                    this.handleCursorErase(true);
                    break;
                case "\x04": // CTRL+D
                    // Send empty input
                    if (this.input === '') {
                        this.resolveInput('')
                        this.activeInput = false;
                    }
            }
        } else {
            this.handleCursorInsert(data);
        }
    }

    writeLine(line) {
        this.xterm.write(line.slice(0, -1))
        this.xterm.write('\r\n');
        return line;
    }

    handleCursorInsert(data) {
        this.input += data;
        this.xterm.write(data)
    }

    handleCursorErase() {
        // Don't delete past the start of input
        if (this.xterm.buffer.active.cursorX <= this.inputStartCursor) {
            return
        }
        this.input = this.input.slice(0, -1)
        this.xterm.write('\x1B[D')
        this.xterm.write('\x1B[P')
    }

    prompt = async () => {
        this.activeInput = true
        // Hack to allow stdout/stderr to finish before we figure out where input starts
        setTimeout(() => {this.inputStartCursor = this.xterm.buffer.active.cursorX}, 1)
        // If line buffer has a line ready, send it immediately
        if (this.inputBuffer.hasLineReady()) {
            return new Promise((resolve, reject) => {
                resolve(this.writeLine(this.inputBuffer.nextLine()));
                this.activeInput = false;
            })
        // If line buffer has an incomplete line, use it for the active line
        } else if (this.inputBuffer.lastLineIsIncomplete()) {
            // Hack to ensure cursor input start doesn't end up after user input
            setTimeout(() => {this.handleCursorInsert(this.inputBuffer.nextLine())}, 1);
        }
        return new Promise((resolve, reject) => {
            this.resolveInput = (value) => {
                resolve(value)
            }
        })
    }

    clear() {
        this.xterm.clear();
    }

    print(charCode) {
        let array = [charCode];
        if (charCode == 10) {
            array = [13, 10];  // Replace \n with \r\n
        }
        this.xterm.write(new Uint8Array(array));
    }
}

class BufferQueue {
    constructor(xterm) {
        this.buffer = []
    }

    isEmpty() {
        return this.buffer.length == 0
    }

    lastLineIsIncomplete() {
        return !this.isEmpty() && !this.buffer[this.buffer.length-1].endsWith("\n")
    }

    hasLineReady() {
        return !this.isEmpty() && this.buffer[0].endsWith("\n")
    }

    addData(data) {
        let lines = data.match(/.*(\n|$)/g)
        if (this.lastLineIsIncomplete()) {
            this.buffer[this.buffer.length-1] += lines.shift()
        }
        for (let line of lines) {
            this.buffer.push(line)
        }
    }

    nextLine() {
        return this.buffer.shift()
    }
}

const runButton = document.getElementById('run')
const replButton = document.getElementById('repl')
const stopButton = document.getElementById('stop')
const clearButton = document.getElementById('clear')

const codeBox = document.getElementById('codebox')

window.onload = () => {
    const terminal = new WasmTerminal()
    terminal.open(document.getElementById('terminal'))

    const stdio = {
        stdout: (charCode) => { terminal.print(charCode) },
        stderr: (charCode) => { terminal.print(charCode) },
        stdin: async () => {
            return await terminal.prompt()
        },
        message: (text) => { terminal.writeLine(`\r\n${text}\r\n`) },
    }

    const programRunning = (isRunning) => {
        if (isRunning) {
            replButton.setAttribute('disabled', true)
            runButton.setAttribute('disabled', true)
            stopButton.removeAttribute('disabled')
        } else {
            replButton.removeAttribute('disabled')
            runButton.removeAttribute('disabled')
            stopButton.setAttribute('disabled', true)
        }
    }

    runButton.addEventListener('click', (e) => {
        terminal.clear()
        programRunning(true)
        const code = codeBox.value
        pythonWorkerManager.run({args: ['main.py'], files: {'main.py': code}})
    })

    replButton.addEventListener('click', (e) => {
        terminal.clear()
        programRunning(true)
        // Need to use "-i -" to force interactive mode.
        // Looks like isatty always returns false in emscripten
        pythonWorkerManager.run({args: ['-i', '-'], files: {}})
    })

    stopButton.addEventListener('click', (e) => {
        programRunning(false)
        pythonWorkerManager.reset()
    })

    clearButton.addEventListener('click', (e) => {
        terminal.clear()
    })

    const readyCallback = () => {
        replButton.removeAttribute('disabled')
        runButton.removeAttribute('disabled')
        clearButton.removeAttribute('disabled')
    }

    const finishedCallback = () => {
        programRunning(false)
    }

    const pythonWorkerManager = new WorkerManager('./python.worker.js', stdio, readyCallback, finishedCallback)
}
    </script>
</head>
<body>
    <h1>Simple REPL for Python WASM</h1>
<textarea id="codebox" cols="108" rows="16">
print('Welcome to WASM!')
</textarea>
    <div class="button-container">
      <button id="run" disabled>Run</button>
      <button id="repl" disabled>Start REPL</button>
      <button id="stop" disabled>Stop</button>
      <button id="clear" disabled>Clear</button>
    </div>
    <div id="terminal"></div>
    <div id="info">
        The simple REPL provides a limited Python experience in the browser.
        <a href="https://github.com/python/cpython/blob/main/Tools/wasm/README.md">
        Tools/wasm/README.md</a> contains a list of known limitations and
        issues. Networking, subprocesses, and threading are not available.
    </div>
</body>
</html>
