"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const AsyncWorker_1 = require("../../../../AsyncWorker");
const Semifunctional_1 = require("../../../../Class/Semifunctional");
const RemotePort_1 = require("../../../../RemotePort");
const STRING_1 = require("../../../../constant/STRING");
const wrap_1 = require("../../../../wrap");
const _ids_1 = require("../../../_ids");
class Remote extends Semifunctional_1.Semifunctional {
    constructor(system) {
        super({
            fi: ['opt'],
            fo: [],
            i: ['close', 'message'],
            o: ['message', 'graph'],
        }, {
            output: {
                graph: {
                    ref: true,
                },
            },
        }, system, _ids_1.ID_REMOTE_GRAPH);
        this._close = () => {
            // console.log('Remote', '_close')
            if (this._remote_port) {
                this._remote_port.close();
                this._remote_port = undefined;
            }
        };
        this.addListener('destroy', () => {
            this._close();
        });
        this.addListener('take_err', () => {
            //
        });
        this.addListener('take_caught_err', () => {
            //
        });
    }
    f({ opt }, done) {
        //
    }
    onIterDataInputData(name, _data) {
        return __awaiter(this, void 0, void 0, function* () {
            // console.log('Remote', 'onIterDataInputData', name, message)
            switch (name) {
                case 'close':
                    this._close();
                    this._done();
                    this._backward('close');
                    break;
                case 'message':
                    {
                        // console.log('Remote', 'message', message)
                        const { type, data } = _data;
                        switch (type) {
                            case STRING_1.EXEC:
                                {
                                    this._port.onmessage({ data });
                                }
                                break;
                            case STRING_1.INIT:
                                {
                                    const port = {
                                        send: (data) => {
                                            // const message = stringify(data)
                                            this._output.message.push(data);
                                        },
                                        onmessage(data) {
                                            // TODO
                                        },
                                        onerror() {
                                            // TODO
                                        },
                                        terminate() {
                                            // TODO
                                        },
                                    };
                                    this._port = port;
                                    const remote_port = new RemotePort_1.RemotePort(port);
                                    this._remote_port = remote_port;
                                    const $graph = (0, AsyncWorker_1.AsyncWorkerGraph)(remote_port);
                                    const graph = (0, wrap_1.$wrap)(this.__system, $graph, [
                                        'U',
                                        'C',
                                        'G',
                                    ]);
                                    this._output.graph.push(graph);
                                }
                                break;
                            case STRING_1.TERMINATE:
                                {
                                    this._close();
                                }
                                break;
                        }
                        this._backward('message');
                    }
                    break;
            }
        });
    }
}
exports.default = Remote;
//# sourceMappingURL=index.js.map