/* eslint no-console: "off"*/
/* eslint max-depth: ["error", 6]*/
/**
 * Copy fields from one object to another
 * @param {Object} target The target to copy to
 * @param {Object} source The source to copy from
 * @param {Array} fields The field names to copy
 * @returns {Object} Reference to target
 */
export function objCopy(target, source, fields) {
    if (fields === undefined || fields === null) {
        fields = Object.getOwnPropertyNames(source);
    }
    for (const ix in fields) {
        const field = fields[ix];
        target[field] = source[field];
    }
    return target;
}

/**
 * Transport items from one object to another
 * @param {Object} target The target to move to
 * @param {Object} source The source to move from
 * @param {*} identifier The value used to match the item
 * @param {string} param The field name to match on (default: 'value')
 */
export function transportItem(target, source, identifier, param) {
    if (!param) {
        param = 'value';
    }
    // Find item
    let item;
    let itemindex;
    for (const ix in source) {
        if (source[ix][param] == identifier) {
            item = source[ix];
            itemindex = ix;
            break;
        }
    }
    if (item) {
        target.push(item);
        source.splice(itemindex, 1);
    }
}

/**
 * Do initial conversion on multiple studyplans
 * @param {Array} studyplans The list of studyplans to load
 * @returns {Array} List of updated studyplans
 */
export function processStudyplans(studyplans) {
    // Unify object references to connections between items, so there are no duplicates
    for (const isx in studyplans) {
        const studyplan = studyplans[isx];
        processStudyplan(studyplan);
    }
    return studyplans;
}

/**
 * Perform initial processing on a downloaded studyplan
 * Mainly used to create the proper references between items
 * @param {Object} studyplan The studyplan to process
 * @returns {object} Processed studyplan
 */
export function processStudyplan(studyplan) {
    for (const ip in studyplan.pages) {
        const page = studyplan.pages[ip];
        processStudyplanPage(page);
    }
    return studyplan;
}

/**
 * Perform initial processing on a downloaded studyplan'page
 * Mainly used to create the proper references between items
 * @param {Object} page The studyplan page to process
 * @returns {object} Processed studyplan
 */
export function processStudyplanPage(page) {
    let connections = {};
    for (const il in page.studylines) {
        const line = page.studylines[il];

        for (const is in line.slots) {
            const slot = line.slots[is];

            if (slot.courses !== undefined) {
                for (const ic in slot.courses) {
                    const itm = slot.courses[ic];

                    for (const idx in itm.connections.in) {
                        const conn = itm.connections.in[idx];

                        if (conn.id in connections) {
                            itm.connections[idx] = connections[conn.id];
                        } else {
                            connections[conn.id] = conn;
                        }
                    }
                    for (const idx in itm.connections.out) {
                        const conn = itm.connections.out[idx];

                        if (conn.id in connections) {
                            itm.connections[idx] = connections[conn.id];
                        } else {
                            connections[conn.id] = conn;
                        }
                    }
                }
            }

            if (slot.filters !== undefined) {
                for (const ix in slot.filters) {
                    const itm = slot.filters[ix];

                    for (const idx in itm.connections.in) {
                        const conn = itm.connections.in[idx];

                        if (conn.id in connections) {
                            itm.connections[idx] = connections[conn.id];
                        } else {
                            connections[conn.id] = conn;
                        }
                    }
                    for (const idx in itm.connections.out) {
                        const conn = itm.connections.out[idx];

                        if (conn.id in connections) {
                            itm.connections[idx] = connections[conn.id];
                        } else {
                            connections[conn.id] = conn;
                        }
                    }
                }
            }
        }
    }
    return page;
}
