"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const http = require("http");
const bsock = require("bsock");
const Util_1 = require("./Util");
class Server {
    constructor(port, rpcExporters = [], conf = {
        errorHandler: (socket) => (error) => { socket.destroy(); console.error(error); },
        closeHandler: (socket) => () => { console.log("Socket closing"); },
        connectionHandler: (socket) => { console.log("New websocket connection in port " + socket.port); },
        visibility: "127.0.0.1"
    }) {
        this.port = port;
        this.rpcExporters = rpcExporters;
        this.conf = conf;
        this.io = bsock.createServer();
        this.wsServer = http.createServer();
        this.startWebsocket();
    }
    startWebsocket() {
        try {
            this.io.attach(this.wsServer);
            this.io.on('socket', (socket) => {
                socket.on('error', this.conf.errorHandler(socket));
                socket.on('close', this.conf.closeHandler(socket));
                if (this.conf.visibility === "127.0.0.1")
                    this.initRPCs(socket);
                else
                    this.initPublicRPCs(socket);
            });
            this.wsServer.listen(this.port, this.conf.visibility);
        }
        catch (e) {
            //@ts-ignore
            this.errorHandler(undefined)("Unable to connect to socket");
        }
    }
    initRPCs(socket) {
        const infoRPC = [
            {
                name: 'info',
                type: 'Call',
                func: async () => rpcInfos
            }
        ];
        const rpcInfos = [
            ...Util_1.rpcHooker(socket, "RPC", infoRPC, false),
            ...this.rpcExporters.flatMap(exporter => Util_1.rpcHooker(socket, exporter.name, [...exporter.exportPublicRPCs(), ...exporter.exportRPCs()]))
        ];
    }
    initPublicRPCs(socket) {
        const rpcInfos = [
            ...Util_1.rpcHooker(socket, "Admin", adminRPCs, false),
            ...this.rpcExporters.flatMap(exporter => Util_1.rpcHooker(socket, exporter.name, exporter.exportPublicRPCs()))
        ];
    }
}
exports.Server = Server;
