"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const express = require("express");
const promClient = require("prom-client");
const Logger_1 = require("../shared/Logger");
class KubernetesServer {
    constructor(config = {}) {
        this.ready = false;
        const logLevel = process.env.LOG_LEVEL || "debug";
        this.logger = new Logger_1.ConsoleLogger(logLevel);
        this.registry = new promClient.Registry();
        this.registry.setDefaultLabels(config.labels || {});
        promClient.collectDefaultMetrics({ register: this.registry });
    }
    start() {
        return __awaiter(this, void 0, void 0, function* () {
            const handler = (signal) => {
                let shutdownPromise;
                return () => __awaiter(this, void 0, void 0, function* () {
                    if (!shutdownPromise) {
                        this.logger.info(`Caught ${signal} signal. Shutting down.`);
                        shutdownPromise = this.shutdown().catch((err) => {
                            this.logger.fatal(`Error stopping server: ${err.message}`);
                            process.exit(1);
                        }).then(() => {
                            this.logger.info(`Exiting gracefully.`);
                            process.exit(0);
                        });
                    }
                });
            };
            process.on("SIGINT", handler("INT"));
            process.on("SIGTERM", handler("TERM"));
            this.unhandledRejectionCallback = (reason, promise) => {
                this.logger.fatal(`Detected an unhandled promise rejection at: ${promise} reason: ${reason.stack}`);
                this.logger.fatal("Exiting code 1");
                process.exit(1);
            };
            process.on("unhandledRejection", this.unhandledRejectionCallback);
            const logMessagesCounter = new promClient.Counter({
                name: "ros_log_messages_total",
                help: "Realm Object Server log message counts",
                labelNames: ["level"],
                registers: [this.registry],
            });
            this.logger.on("message", (level, message) => logMessagesCounter.inc({ level }));
            const internalExpress = express();
            internalExpress.get("/healthz", (req, res) => res.sendStatus(200));
            internalExpress.get("/readz", (req, res) => res.sendStatus(this.ready ? 200 : 503));
            internalExpress.get("/metrics", (req, res) => res.send(this.getMetrics()));
            this.internalServer = yield new Promise((resolve) => {
                const port = Number(process.env.INTERNAL_PORT || 9081);
                const listener = internalExpress.listen(port, "0.0.0.0", () => {
                    resolve(listener);
                });
            });
        });
    }
    shutdown() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.internalServer) {
                yield this.internalServer.close();
                delete this.internalServer;
            }
            if (this.unhandledRejectionCallback) {
                process.removeListener('unhandledRejection', this.unhandledRejectionCallback);
                delete this.unhandledRejectionCallback;
            }
        });
    }
    getMetrics() {
        return this.registry.metrics();
    }
}
exports.KubernetesServer = KubernetesServer;
//# sourceMappingURL=KubernetesServer.js.map