<!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) {
        this.workerURL = workerURL
        this.worker = null
        this.standardIO = standardIO
        this.readyCallBack = readyCallBack

        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 || {}
        })
    }

    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.stderr(`Exited with status: ${event.data.returnCode}\r\n`)
        }
    }
}

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
                case "\x04": // CTRL+D
                    this.handleCursorErase(true);
                    break;
            }
        } 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 replButton = document.getElementById('repl')
const clearButton = document.getElementById('clear')

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()
        }
    }

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

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

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

    const pythonWorkerManager = new WorkerManager('./python.worker.js', stdio, readyCallback)
}
    </script>
</head>
<body>
    <h1>Simple REPL for Python WASM</h1>
    <div id="terminal"></div>
    <div class="button-container">
      <button id="repl" disabled>Start REPL</button>
      <button id="clear" disabled>Clear</button>
    </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>
