"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnvConfiguration = exports.Configuration = exports.numberConfig = exports.booleanConfig = exports.stringConfig = exports.getConfigDeclarations = void 0;
const dotenv_1 = __importDefault(require("dotenv"));
const exception_js_1 = require("./exception.js");
dotenv_1.default.config();
const CONFIG_GLOBAL_KEY = Symbol.for('@automationcloud/autopilot:configDeclarations');
function getConfigDeclarations() {
    let map = global[CONFIG_GLOBAL_KEY];
    if (!(map instanceof Map)) {
        map = new Map();
        global[CONFIG_GLOBAL_KEY] = map;
    }
    return map;
}
exports.getConfigDeclarations = getConfigDeclarations;
function stringConfig(key, defaultValue) {
    return declare({
        type: 'string',
        key,
        defaultValue,
        parse(str) {
            return str;
        }
    });
}
exports.stringConfig = stringConfig;
function booleanConfig(key, defaultValue) {
    return declare({
        type: 'boolean',
        key,
        defaultValue,
        parse(str) {
            return str === 'true';
        }
    });
}
exports.booleanConfig = booleanConfig;
function numberConfig(key, defaultValue) {
    return declare({
        type: 'number',
        key,
        defaultValue,
        parse(str) {
            return Number(str);
        }
    });
}
exports.numberConfig = numberConfig;
function declare(decl) {
    getConfigDeclarations().set(decl.key, decl);
    return decl;
}
class Configuration {
    constructor() {
        this.values = new Map();
    }
    resolve(decl) {
        const str = this.values.get(decl.key);
        if (str != null) {
            return decl.parse(str);
        }
        if (decl.defaultValue != null) {
            return decl.defaultValue;
        }
        return null;
    }
    get(decl) {
        const val = this.resolve(decl);
        if (val != null) {
            return val;
        }
        throw new exception_js_1.Exception({
            name: 'ConfigurationError',
            message: `Configuration ${decl.key} not provided`,
        });
    }
    setAll(object) {
        for (const [key, value] of Object.entries(object)) {
            if (value != null) {
                this.values.set(key, value?.trim());
            }
        }
    }
    getMissingConfigs() {
        const missing = [];
        for (const decl of getConfigDeclarations().values()) {
            if (this.resolve(decl) == null) {
                missing.push(decl);
            }
        }
        return missing;
    }
}
exports.Configuration = Configuration;
class EnvConfiguration extends Configuration {
    constructor() {
        super();
        this.setAll(process.env);
    }
}
exports.EnvConfiguration = EnvConfiguration;
//# sourceMappingURL=config.js.map