"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectionString = void 0;
const node_util_1 = require("node:util");
const connection_string_parser_1 = __importDefault(require("./parser/connection-string-parser"));
class ConnectionString {
    #connectionString;
    #parsed;
    constructor(connectionString) {
        this.#connectionString = connectionString.toString();
        const parsed = (0, connection_string_parser_1.default)(this.#connectionString);
        this.#parsed = new Map(Object.entries(parsed));
    }
    [node_util_1.inspect.custom]() {
        return this.#parsed;
    }
    get size() {
        return this.#parsed.size;
    }
    // it would be really nice to be able to make this a generice (eg: get<string>) and that would then coerce the value
    // see typia library for an example of something similar
    get(key, coerceType) {
        const val = this.#parsed.get(key.toLowerCase());
        const actualType = coerceType ?? 'string';
        if (typeof val === 'undefined' || actualType === 'string') {
            return val;
        }
        switch (actualType) {
            case 'boolean':
                return (['false', 'no', '0'].includes(val.toLowerCase()) ? false : !!val);
            case 'number':
                return parseInt(val, 10);
            default:
                throw new TypeError('Coerce type not supported');
        }
    }
    keys() {
        return this.#parsed.keys();
    }
    values() {
        return this.#parsed.values();
    }
    [Symbol.iterator]() {
        return this.#parsed[Symbol.iterator]();
    }
    entries() {
        return this.#parsed.entries();
    }
    toString() {
        return this.#connectionString;
    }
    has(key) {
        return this.#parsed.has(key.toLowerCase());
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    forEach(callbackfn, thisArg) {
        this.#parsed.forEach((value, key) => {
            callbackfn.call(thisArg ?? this, value, key, this);
        });
    }
    // a way to extract a formatted object from the connection string
    toSchema(schema, { includeMissing } = {}) {
        return Object.fromEntries(Object.entries(schema).reduce((props, [key, { type, default: defaultValue, aliases }]) => {
            // try to find the property
            const prop = [key, ...aliases ?? []].find((k) => this.has(k));
            if (prop || includeMissing) {
                props.push([key, prop ? this.get(prop.toLowerCase(), type) : defaultValue]);
            }
            return props;
        }, []));
    }
}
exports.ConnectionString = ConnectionString;
//# sourceMappingURL=connection-string.js.map