"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const typed_json_rpc_websocket_server_1 = require("@hediet/typed-json-rpc-websocket-server");
const cli_lib_1 = require("@hediet/cli-lib");
const uiContract_1 = require("./uiContract");
const chromeLauncher = require("chrome-launcher");
const http = require("http");
const finalhandler = require("finalhandler");
const serveStatic = require("serve-static");
const path_1 = require("path");
const typed_json_rpc_1 = require("@hediet/typed-json-rpc");
async function showGui(cli, run, selectedCmd, verbose) {
    let chrome;
    const { httpServerDisposable, httpServerPort } = startHttpServer();
    const server = typed_json_rpc_websocket_server_1.startWebSocketServer({ port: 0 }, async (stream) => {
        const { channel } = uiContract_1.uiContract.registerServerToStream(stream, verbose ? new typed_json_rpc_1.ConsoleRpcLogger() : undefined, {
            getSchema: async () => {
                const schema = cli_lib_1.cliToSchema(cli);
                schema.defaultType = selectedCmd
                    ? selectedCmd.getSerializer().namespacedName
                    : undefined;
                const json = cli_lib_1.sSchema.serialize(schema);
                return json;
            },
            run: async (args) => {
                const s = cli.getSerializer();
                const o = s.deserialize(args.args).unwrap();
                const data = o.getData();
                run(data);
                server.close();
            },
        });
        channel.sendExceptionDetails = true;
        await stream.onClosed;
        server.dispose();
        httpServerDisposable.dispose();
        if (chrome) {
            chrome.dispose();
        }
    });
    await server.onListening;
    const websocketPort = server.port;
    try {
        const url = `http://localhost:${httpServerPort}/?wsPort=${websocketPort}`;
        try {
            chrome = await launchChrome(url);
        }
        catch (e) {
            if (verbose) {
                console.log("Error while launching chrome:", e);
            }
        }
        console.log(url);
    }
    catch (error) { }
}
exports.showGui = showGui;
function startHttpServer() {
    const root = path_1.join(__dirname, "../../ui/dist");
    const serve = serveStatic(root, {
        index: ["index.html"],
    });
    const httpServer = http.createServer(function onRequest(req, res) {
        serve(req, res, finalhandler(req, res));
    });
    httpServer.listen();
    const httpServerPort = httpServer.address().port;
    return {
        httpServerDisposable: {
            dispose: () => {
                httpServer.close();
            },
        },
        httpServerPort,
    };
}
async function launchChrome(url) {
    const width = 700;
    const height = 500;
    const chrome = await chromeLauncher.launch({
        startingUrl: url,
        chromeFlags: ["--app=" + url, `--window-size=${width},${height}`],
    });
    return {
        dispose: () => {
            if (!chrome.process.killed) {
                try {
                    chrome.process.kill();
                }
                catch (e) {
                    // chrome should exit on its own when connection closes anyways
                }
            }
        },
    };
}
//# sourceMappingURL=showGui.js.map