"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 services = require("./services");
const kubernetes_1 = require("./kubernetes");
const Server_1 = require("./Server");
const StaticDiscovery_1 = require("./discovery/StaticDiscovery");
const stats_1 = require("./stats");
const YAML = require("yamljs");
const fs = require("fs-extra");
const tmp = require("tmp");
const PrometheusStatsSink_1 = require("./stats/PrometheusStatsSink");
;
class KubernetesCoreServices extends kubernetes_1.KubernetesServer {
    constructor() {
        super({ labels: { component: "core" } });
        this.listenPort = Number(process.env.CORE_SERVICES_HTTP_PORT || 9080);
        this.configPath = process.env.CORE_SERVICES_CONFIG_PATH || "/config/core-services.yaml";
        this.discoveryConfigPath = process.env.DISCOVERY_CONFIG_PATH;
        if (!this.discoveryConfigPath) {
            throw new Error("Environment variable DISCOVERY_CONFIG_PATH is not defined");
        }
        this.publicKeyPath = process.env.PUBLIC_KEY_PATH;
        if (!this.publicKeyPath) {
            throw new Error("PUBLIC_KEY_PATH environment variable is not defined");
        }
        this.privateKeyPath = process.env.PRIVATE_KEY_PATH;
        if (!this.privateKeyPath) {
            throw new Error("PRIVATE_KEY_PATH environment variable is not defined");
        }
    }
    start() {
        const _super = name => super[name];
        return __awaiter(this, void 0, void 0, function* () {
            yield _super("start").call(this);
            const serviceConfigs = YAML.parse(fs.readFileSync(this.configPath, "utf-8"));
            this.realmObjectServer = new Server_1.Server();
            const config = YAML.parse(fs.readFileSync(this.discoveryConfigPath, "utf-8"));
            const discovery = new StaticDiscovery_1.StaticDiscovery({ config });
            for (const name in serviceConfigs) {
                const serviceConfig = serviceConfigs[name];
                const serviceClass = services[name];
                if (!serviceClass) {
                    throw new Error(`No class found for service: ${name}`);
                }
                const service = new serviceClass(serviceConfig);
                if (name === "AuthService") {
                    if (serviceConfig.enableRuntimeConfiguration === true) {
                        service.setDefaultProviders(serviceConfig.defaultProviders);
                    }
                    else {
                    }
                }
                this.realmObjectServer.addServices(service);
            }
            const tmpDir = tmp.dirSync();
            const statsSink = new PrometheusStatsSink_1.PrometheusStatsSink({ registry: this.registry });
            yield this.realmObjectServer.start({
                discovery, statsSink,
                logger: this.logger,
                dataPath: tmpDir.name,
                address: "0.0.0.0",
                port: this.listenPort,
                autoKeyGen: false,
                privateKeyPath: this.privateKeyPath,
                publicKeyPath: this.publicKeyPath,
                statsStorage: new stats_1.NullStatsStorage(),
            });
        });
    }
    shutdown() {
        const _super = name => super[name];
        return __awaiter(this, void 0, void 0, function* () {
            if (this.realmObjectServer) {
                yield this.realmObjectServer.shutdown().catch((err) => {
                    this.logger.warn(`Error stopping ROS: ${err.message}`);
                });
                delete this.realmObjectServer;
            }
            yield _super("shutdown").call(this);
        });
    }
}
if (!module.parent) {
    const server = new KubernetesCoreServices();
    server.start().catch((err) => {
        console.log(`Could not start server: ${err.stack}`);
        process.exit(1);
    });
}
//# sourceMappingURL=KubernetesCoreServices.js.map