"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.prototypeChain = prototypeChain;
exports.installPasteSupport = installPasteSupport;
exports.fixNode60446 = fixNode60446;
const stream_1 = require("stream");
function* prototypeChain(obj) {
    if (!obj)
        return;
    yield obj;
    yield* prototypeChain(Object.getPrototypeOf(obj));
}
function installPasteSupport(repl) {
    if (!repl.terminal || process.env.TERM === 'dumb')
        return '';
    repl.output.write('\x1b[?2004h');
    const onEnd = '\x1b[?2004l';
    const ttyWriteKey = [...prototypeChain(repl)]
        .flatMap((proto) => Object.getOwnPropertySymbols(proto))
        .find((s) => String(s).includes('(_ttyWrite)'));
    if (!ttyWriteKey)
        throw new Error('Could not find _ttyWrite key on readline instance');
    repl.input.on('keypress', (s, key) => {
        if (key.name === 'paste-start') {
            if (Object.prototype.hasOwnProperty.call(repl, ttyWriteKey))
                throw new Error('Unexpected existing own _ttyWrite key on readline instance');
            const origTtyWrite = repl[ttyWriteKey];
            Object.defineProperty(repl, ttyWriteKey, {
                value: function (s, key) {
                    if (key.ctrl || key.meta || key.code) {
                        return;
                    }
                    if (key.name &&
                        key.name !== key.sequence?.toLowerCase() &&
                        !['tab', 'return', 'enter', 'space'].includes(key.name)) {
                        return;
                    }
                    return origTtyWrite.call(this, s, key);
                },
                enumerable: false,
                writable: true,
                configurable: true,
            });
        }
        else if (key.name === 'paste-end') {
            delete repl[ttyWriteKey];
        }
    });
    return onEnd;
}
function _hasNode60446() {
    const { start } = require('repl');
    const input = new stream_1.PassThrough();
    const output = new stream_1.PassThrough();
    const repl = start({ terminal: true, input, output, useColors: false });
    repl.input.emit('data', '{}');
    repl.input.emit('keypress', '', { name: 'left' });
    repl.input.emit('data', 'node');
    const { line } = repl;
    repl.close();
    return line === '{}noed';
}
let hasNode60446 = undefined;
function fixNode60446(repl) {
    hasNode60446 ??= _hasNode60446();
    if (!hasNode60446)
        return;
    const symbols = [...prototypeChain(repl)].flatMap((proto) => Object.getOwnPropertySymbols(proto));
    const insertStringKey = symbols.find((s) => String(s).includes('(_insertString)'));
    const writeToOutputKey = symbols.find((s) => String(s).includes('(_writeToOutput)'));
    if (!insertStringKey || !writeToOutputKey)
        return;
    const original = repl[insertStringKey];
    let fixupOnWriteToOutput;
    Object.defineProperty(repl, insertStringKey, {
        configurable: true,
        writable: true,
        enumerable: false,
        value: function (s) {
            if (!this.isCompletionEnabled) {
                const origLine = this.line;
                const origCursor = this.cursor;
                fixupOnWriteToOutput = () => {
                    const beg = origLine.slice(0, origCursor);
                    const end = origLine.slice(origCursor);
                    this.line = beg + s + end;
                };
            }
            return original.call(this, s);
        },
    });
    const originalWriteToOutput = repl[writeToOutputKey];
    Object.defineProperty(repl, writeToOutputKey, {
        configurable: true,
        writable: true,
        enumerable: false,
        value: function (s) {
            fixupOnWriteToOutput?.();
            fixupOnWriteToOutput = undefined;
            return originalWriteToOutput.call(this, s);
        },
    });
}
//# sourceMappingURL=repl-paste-support.js.map