"use strict";
///<reference path="../lib.deno.d.ts" />
Object.defineProperty(exports, "__esModule", { value: true });
exports.stderr = exports.stdout = exports.stdin = void 0;
function chain(fn, cleanup) {
    let prev;
    return function _fn(...args) {
        const curr = (prev || Promise.resolve())
            .then(() => fn(...args))
            .finally(cleanup || (() => { }))
            .then((result) => {
            if (prev === curr)
                prev = undefined;
            return result;
        });
        return (prev = curr);
    };
}
exports.stdin = {
    rid: 0,
    read: chain((p) => {
        return new Promise((resolve, reject) => {
            process.stdin.resume();
            process.stdin.on("error", onerror);
            process.stdin.once("readable", () => {
                var _a;
                process.stdin.off("error", onerror);
                const data = (_a = process.stdin.read(p.length)) !== null && _a !== void 0 ? _a : process.stdin.read();
                if (data) {
                    p.set(data);
                    resolve(data.length > 0 ? data.length : null);
                }
                else {
                    resolve(null);
                }
            });
            function onerror(error) {
                reject(error);
                process.stdin.off("error", onerror);
            }
        });
    }, () => process.stdin.pause()),
    get readable() {
        throw new Error("Not implemented.");
    },
    readSync() {
        // Node.js doesn't support readSync for stdin
        throw new Error("Not implemented.");
    },
    close() {
        process.stdin.destroy();
    },
    setRaw(mode, options) {
        if (options === null || options === void 0 ? void 0 : options.cbreak) {
            throw new Error("The cbreak option is not implemented.");
        }
        process.stdin.setRawMode(mode);
    },
};
exports.stdout = {
    rid: 1,
    write: chain((p) => {
        return new Promise((resolve) => {
            const result = process.stdout.write(p);
            if (!result) {
                process.stdout.once("drain", () => resolve(p.length));
            }
            else {
                resolve(p.length);
            }
        });
    }),
    get writable() {
        throw new Error("Not implemented.");
    },
    writeSync() {
        // Node.js doesn't support writeSync for stdout
        throw new Error("Not implemented");
    },
    close() {
        process.stdout.destroy();
    },
};
exports.stderr = {
    rid: 2,
    write: chain((p) => {
        return new Promise((resolve) => {
            const result = process.stderr.write(p);
            if (!result) {
                process.stderr.once("drain", () => resolve(p.length));
            }
            else {
                resolve(p.length);
            }
        });
    }),
    get writable() {
        throw new Error("Not implemented.");
    },
    writeSync() {
        // Node.js doesn't support writeSync for stderr
        throw new Error("Not implemented");
    },
    close() {
        process.stderr.destroy();
    },
};
