"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bootModuleServer = void 0;
const tslib_1 = require("tslib");
const logger_1 = require("@refloat/logger");
const http_1 = require("http");
const cross_fetch_1 = (0, tslib_1.__importDefault)(require("cross-fetch"));
const fetch_1 = require("./fetch");
const logger = logger_1.Logger.create('module-server');
async function bootModuleServer(port = 9090) {
    const reader = new fetch_1.ModuleReader();
    const server = (0, http_1.createServer)((req, res) => {
        var _a;
        const uri = (_a = req.url) === null || _a === void 0 ? void 0 : _a.slice(1);
        if (uri) {
            const query = new URLSearchParams(uri);
            const checkoutPath = query.get('checkout');
            if (checkoutPath) {
                logger.verbose('checking out module file', { file: checkoutPath });
                return reader
                    .checkout(checkoutPath)
                    .then((contents) => res.end(contents))
                    .catch((error) => {
                    console.error(error);
                    res.statusCode = 500;
                    res.end();
                });
            }
            const readFile = query.get('read');
            if (readFile) {
                logger.verbose('reading module file', { file: readFile });
                return reader
                    .read(readFile)
                    .then((contents) => {
                    if (contents === null) {
                        res.statusCode = 404;
                        res.end(`file "${readFile}" not found`);
                    }
                    else {
                        res.end(contents);
                    }
                })
                    .catch((error) => {
                    console.error(error);
                    res.statusCode = 500;
                    res.end(String(error));
                });
            }
            const shaFile = query.get('sha');
            if (shaFile) {
                logger.verbose('reading module SHA', { file: shaFile });
                return reader
                    .sha(shaFile)
                    .then((sha) => res.end(sha))
                    .catch((error) => {
                    console.error(error);
                    res.statusCode = 500;
                    res.end();
                });
            }
            res.statusCode = 404;
            res.end();
        }
    });
    const listening = await new Promise((resolve, reject) => server
        .listen(port, () => resolve(true))
        .once('error', (error) => (error === null || error === void 0 ? void 0 : error['code']) === 'EADDRINUSE' ? resolve(false) : reject(error)));
    if (listening) {
        logger.verbose('module server listening', { port });
    }
    const get = client(port);
    return {
        close: () => new Promise((resolve, reject) => listening
            ? server.close((error) => (error ? reject(error) : resolve()))
            : resolve()),
        checkout: async (source) => get('checkout', source),
        sha: async (file) => get('sha', file),
        get: async (file) => get('read', file, null),
    };
}
exports.bootModuleServer = bootModuleServer;
function client(port) {
    return async function get(name, query, on404) {
        const res = await (0, cross_fetch_1.default)(`http://127.0.0.1:${port}?${name}=${encodeURIComponent(query)}`);
        const text = await res.text();
        if (res.status === 200) {
            return text;
        }
        else if (res.status === 404 && typeof on404 !== 'undefined') {
            return on404;
        }
        else {
            throw new Error(text.trim() || `HTTP error ${res.status}`);
        }
    };
}
//# sourceMappingURL=server.js.map