"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDataLake = getDataLake;
exports.isEnterprise = isEnterprise;
exports.isAtlas = isAtlas;
exports.isLocalAtlas = isLocalAtlas;
exports.isAtlasStream = isAtlasStream;
exports.isLocalhost = isLocalhost;
exports.isDigitalOcean = isDigitalOcean;
exports.getGenuineMongoDB = getGenuineMongoDB;
exports.identifyServerName = identifyServerName;
exports.getBuildEnv = getBuildEnv;
const mongodb_connection_string_url_1 = __importDefault(require("mongodb-connection-string-url"));
const debug_1 = require("debug");
const debug = (0, debug_1.debug)('mongodb-build-info');
const ATLAS_REGEX = /\.mongodb(-dev|-qa|-stage)?\.net$/i;
const ATLAS_STREAM_REGEX = /^atlas-stream-.+/i;
const LOCALHOST_REGEX = /^(localhost|127\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])|0\.0\.0\.0|(?:0*:)*?:?0*1)$/i;
const DIGITAL_OCEAN_REGEX = /\.mongo\.ondigitalocean\.com$/i;
const COSMOS_DB_REGEX = /\.cosmos\.azure\.com$/i;
const DOCUMENT_DB_REGEX = /docdb(-elastic)?\.amazonaws\.com$/i;
const FIRESTORE_REGEX = /\.firestore.goog$/i;
function isRecord(value) {
    return typeof value === 'object' && value !== null;
}
function getDataLake(buildInfo) {
    if (isRecord(buildInfo) &&
        isRecord(buildInfo.dataLake) &&
        typeof buildInfo.dataLake.version === 'string') {
        return {
            isDataLake: true,
            dlVersion: buildInfo.dataLake.version,
        };
    }
    else {
        return {
            isDataLake: false,
            dlVersion: null,
        };
    }
}
function isEnterprise(buildInfo) {
    if (!isRecord(buildInfo)) {
        return false;
    }
    if (typeof buildInfo.gitVersion === 'string' &&
        buildInfo.gitVersion.match(/enterprise/)) {
        return true;
    }
    if (Array.isArray(buildInfo.modules) &&
        buildInfo.modules.indexOf('enterprise') !== -1) {
        return true;
    }
    return false;
}
function getHostnameFromHost(host) {
    if (host.startsWith('[')) {
        return host.substring(1).split(']')[0];
    }
    return host.split(':')[0];
}
function getHostnameFromUrl(url) {
    if (typeof url !== 'string') {
        return '';
    }
    try {
        const connectionString = new mongodb_connection_string_url_1.default(url);
        return getHostnameFromHost(connectionString.hosts[0]);
    }
    catch (e) {
        return getHostnameFromHost(url);
    }
}
function isAtlas(uri) {
    return !!getHostnameFromUrl(uri).match(ATLAS_REGEX);
}
async function isLocalAtlas(countFn) {
    try {
        const count = await countFn('admin', 'atlascli', {
            managedClusterType: 'atlasCliLocalDevCluster',
        });
        return count > 0;
    }
    catch {
        return false;
    }
}
function isAtlasStream(uri) {
    const host = getHostnameFromUrl(uri);
    return !!(host.match(ATLAS_REGEX) && host.match(ATLAS_STREAM_REGEX));
}
function isLocalhost(uri) {
    return !!getHostnameFromUrl(uri).match(LOCALHOST_REGEX);
}
function isDigitalOcean(uri) {
    return !!getHostnameFromUrl(uri).match(DIGITAL_OCEAN_REGEX);
}
function getGenuineMongoDB(uri) {
    const hostname = getHostnameFromUrl(uri);
    if (hostname.match(COSMOS_DB_REGEX)) {
        return {
            isGenuine: false,
            serverName: 'cosmosdb',
        };
    }
    if (hostname.match(DOCUMENT_DB_REGEX)) {
        return {
            isGenuine: false,
            serverName: 'documentdb',
        };
    }
    return {
        isGenuine: true,
        serverName: 'mongodb',
    };
}
async function identifyServerName({ connectionString, adminCommand, }) {
    try {
        const hostname = getHostnameFromUrl(connectionString);
        if (hostname.match(ATLAS_REGEX)) {
            return 'mongodb';
        }
        if (hostname.match(COSMOS_DB_REGEX)) {
            return 'cosmosdb';
        }
        if (hostname.match(DOCUMENT_DB_REGEX)) {
            return 'documentdb';
        }
        if (hostname.match(FIRESTORE_REGEX)) {
            return 'firestore';
        }
        const candidates = await Promise.all([
            adminCommand({ buildInfo: 1 }).then((response) => {
                if ('ferretdb' in response) {
                    return ['ferretdb'];
                }
                else {
                    return [];
                }
            }, (error) => {
                debug('buildInfo command failed %O', error);
                return [];
            }),
            adminCommand({ getParameter: 'foo' }).then(() => [], (error) => {
                if (error instanceof Error && /documentdb_api/.test(error.message)) {
                    return ['pg_documentdb'];
                }
                else {
                    return [];
                }
            }),
        ]).then((results) => results.flat());
        if (candidates.length === 0) {
            return 'mongodb';
        }
        else if (candidates.length === 1) {
            return candidates[0];
        }
        else {
            return 'unknown';
        }
    }
    catch (error) {
        debug('Failed to identify server name', error);
        return 'unknown';
    }
}
function getBuildEnv(buildInfo) {
    if (!isRecord(buildInfo) || !isRecord(buildInfo.buildEnvironment)) {
        return { serverOs: null, serverArch: null };
    }
    const { buildEnvironment } = buildInfo;
    return {
        serverOs: typeof buildEnvironment.target_os === 'string'
            ? buildEnvironment.target_os
            : null,
        serverArch: typeof buildEnvironment.target_arch === 'string'
            ? buildEnvironment.target_arch
            : null,
    };
}
exports.default = {
    getDataLake,
    isEnterprise,
    isAtlas,
    isAtlasStream,
    isLocalhost,
    isDigitalOcean,
    getGenuineMongoDB,
    identifyServerName,
    getBuildEnv,
};
//# sourceMappingURL=index.js.map