"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.isDefined = isDefined;
exports.isNullish = isNullish;
exports.isString = isString;
exports.readNonEmptyString = readNonEmptyString;
exports.roundToDecimals = roundToDecimals;
exports.isWholeNumber = isWholeNumber;
exports.isFulfilledPromise = isFulfilledPromise;
exports.isRejectedPromise = isRejectedPromise;
exports.stringify = stringify;
exports.stringifyIfPresent = stringifyIfPresent;
exports.getCliVersion = getCliVersion;
exports.getCliName = getCliName;
exports.extractKeyCountsFromArgs = extractKeyCountsFromArgs;
exports.getCaseInsensitiveProperty = getCaseInsensitiveProperty;
exports.createStringAndBufferReplacer = createStringAndBufferReplacer;
exports.traverseAndReplaceStrings = traverseAndReplaceStrings;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const possibleCliPackagePaths = Object.freeze([
    '../package.json',
    '../../package.json',
]);
let cliPackage;
function getCliPackage() {
    if (cliPackage) {
        return cliPackage;
    }
    const packagePath = possibleCliPackagePaths
        .map((relativePath) => path.resolve(__dirname, relativePath))
        .find((path) => fs.existsSync(path));
    if (!packagePath) {
        throw new Error('Cannot find package.json');
    }
    const rawData = fs.readFileSync(packagePath);
    cliPackage = JSON.parse(rawData.toString());
    return cliPackage;
}
function isDefined(value) {
    return value !== undefined;
}
function isNullish(value) {
    return value === null || value === undefined;
}
function isString(value) {
    return typeof value === 'string';
}
function readNonEmptyString(value) {
    return typeof value === 'string' && value.length > 0 ? value : undefined;
}
function roundToDecimals(value, decimals) {
    const factor = 10 ** decimals;
    return Math.round(value * factor) / factor;
}
function isWholeNumber(value) {
    if (!value) {
        return false;
    }
    const parsed = isString(value) ? Number(value) : value;
    return parsed - Math.floor(parsed) === 0;
}
function isFulfilledPromise(settledPromise) {
    return settledPromise.status === 'fulfilled';
}
function isRejectedPromise(settledPromise) {
    return settledPromise.status === 'rejected';
}
function stringify(value) {
    if (isNullish(value)) {
        return '';
    }
    if (typeof value === 'object') {
        return JSON.stringify(value);
    }
    return value.toString();
}
function stringifyIfPresent(value) {
    if (isNullish(value)) {
        return;
    }
    return stringify(value);
}
function getCliVersion() {
    return getCliPackage().version;
}
function getCliName() {
    return getCliPackage().name;
}
function extractKeyCountsFromArgs(argv) {
    const ignoreKeys = ['$0', '_'];
    const keysUsed = Object.keys(argv)
        .filter((key) => !ignoreKeys.includes(key))
        .filter((key) => !/[A-Z]/.test(key));
    const keyValueCountMap = {};
    keysUsed.forEach((key) => {
        const value = argv[key];
        let count;
        if (value === undefined || value === null) {
            count = 0;
        }
        else {
            switch (typeof value) {
                case 'bigint':
                case 'number':
                case 'string':
                case 'boolean':
                case 'function':
                case 'symbol':
                    count = 1;
                    break;
                case 'object':
                    if (value instanceof Array) {
                        count = value.length;
                        break;
                    }
                    count = 1;
                    break;
                default:
                    count = 0;
            }
        }
        keyValueCountMap[key] = count;
    });
    return keyValueCountMap;
}
function getCaseInsensitiveProperty(obj, key) {
    const keyInObject = Object.keys(obj).find((k) => k.toLowerCase() === key.toLowerCase());
    if (keyInObject !== undefined) {
        return obj[keyInObject];
    }
    return undefined;
}
function createStringAndBufferReplacer(textReplacer) {
    return (key, value) => {
        if (key === 'type' && value === 'Buffer') {
            return value;
        }
        if (typeof value === 'string') {
            return textReplacer(value);
        }
        if (typeof value === 'object' && value instanceof Buffer) {
            return Buffer.from(textReplacer(value.toString()));
        }
        if (typeof value === 'object' &&
            value !== null &&
            value.type === 'Buffer' &&
            Array.isArray(value.data)) {
            const dataAsString = Buffer.from(value.data).toString();
            const maskedData = textReplacer(dataAsString);
            const newBuffer = Buffer.from(maskedData);
            return newBuffer.toJSON();
        }
        return value;
    };
}
function traverseAndReplaceStrings(obj, replace) {
    const replacer = createStringAndBufferReplacer(replace);
    return JSON.parse(JSON.stringify(obj, replacer));
}
