import { string_capitalize } from "../../primitives/strings/string_capitalize.js";

/**
 * @template T
 * @param {Object} root
 * @param {string[]} parts
 * @param {number} part_offset
 * @param {number} part_count
 * @param {boolean} [throw_on_missing] will throw an exception if property is not found
 * @returns {undefined|T}
 */
export function read_property(
    root,
    parts, part_offset, part_count,
    throw_on_missing = false
) {

    let thing = root;

    for (let i = 0; i < part_count; i++) {

        const part = parts[i + part_offset];

        if (typeof thing[part] !== 'undefined') {
            thing = thing[part];
        } else {
            const getter_name = `get${string_capitalize(part)}`;
            const getter = thing[getter_name];

            if (typeof getter === "function") {
                // resolve via getter
                thing = getter.call(thing);
            } else if(throw_on_missing){
                // no getter
                throw new Error(`No no property or getter found for '${part}' on [${i}]'${parts.slice(part_offset, part_offset + part_count).join('/')}'`);
            }else{
                // no getter
                return undefined;
            }
        }

    }

    return thing;
}
