"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Holder_1 = require("../../../../../../Class/Holder");
const EventEmitter_1 = require("../../../../../../EventEmitter");
const APINotImplementedError_1 = require("../../../../../../exception/APINotImplementedError");
const ReadableStream_1 = require("../../../../../../wrap/ReadableStream");
const _ids_1 = require("../../../../../_ids");
class ReadableStream_ extends Holder_1.Holder {
    constructor(system) {
        super({
            fi: ['opt'],
            fo: ['stream'],
            i: ['data', 'end'],
            o: ['done'],
        }, {
            input: {
                body: {
                    ref: true,
                },
            },
            output: {
                res: {
                    ref: true,
                },
            },
        }, system, _ids_1.ID_READABLE_STREAM);
        this._input_data = (data) => {
            this._emitter.emit('data', data);
            this._input.data.pull();
        };
        this._input_end = () => {
            this._emitter.emit('end');
            this.d();
            this._input.end.pull();
        };
    }
    async f({ opt }, done, fail) {
        const { api: { window: { ReadableStream }, text: { TextEncoder }, }, } = this.__system;
        if (!ReadableStream) {
            fail((0, APINotImplementedError_1.apiNotSupportedError)('ReadableStream'));
            return;
        }
        const emitter = new EventEmitter_1.EventEmitter_();
        this._emitter = emitter;
        const encoder = new TextEncoder();
        const readableStream = new ReadableStream({
            start(controller) {
                emitter.addListener('data', (chunk) => {
                    controller.enqueue(encoder.encode(chunk));
                });
                emitter.addListener('end', () => {
                    controller.close();
                });
                emitter.addListener('error', (err) => {
                    controller.error(err);
                });
            },
        });
        const stream = (0, ReadableStream_1.wrapReadableStream)(readableStream, this.__system);
        if (this._input.data.active()) {
            this._input_data(this._input.data.peak());
        }
        if (this._input.end.active()) {
            this._input_end();
        }
        done({ stream });
    }
    onIterDataInputData(name, data) {
        super.onIterDataInputData(name, data);
        if (this._emitter) {
            if (name === 'data') {
                this._input_data(data);
            }
            else if (name === 'end') {
                this._input_end();
            }
        }
    }
    b() {
        this._output.done.push(true);
    }
}
exports.default = ReadableStream_;
//# sourceMappingURL=index.js.map