import { objectHasProperty } from "./objectHasProperty.js";

/**
 *
 * @param {Object} current
 * @returns {string[]}
 */
function buildErrorSuggestions(current) {
    const options = Object.keys(current);

    const n = options.length;
    const limit = 10;

    if (n > limit) {
        options.splice(0, limit);
        options.push(`[... ${n - limit} more options]`);
    }

    return options;
}

/**
 *
 * @param {object} object
 * @param {string[]} parts
 * @param {function} [missingPropertyHandler] Allows custom handling of missing properties
 * @returns {*}
 * @throws {Error} if a path can not be resolved
 */
export function resolvePathByArray(object, parts, missingPropertyHandler) {
    let current = object;

    if (parts.length > 0 && parts[0] === "") {
        //if the first element is empty, remove it. Case of "/a/b/c"
        parts.shift();
    }

    const l = parts.length;
    for (let i = 0; i < l; i++) {
        const part = parts[i];
        if (!objectHasProperty(current, part)) {
            if (typeof missingPropertyHandler === "function") {
                missingPropertyHandler(current, part, i, l);
            } else {
                const options = buildErrorSuggestions(current);

                throw new Error(`failed to resolve path [${parts.join(',')}] at part ${i} [${part}]. Existing keys: ${options.join(", ")}`);
            }
        }
        current = current[part];
    }
    return current;
}
