"use strict";
/*
 * Copyright (c) 2021-2022.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseQueryFields = void 0;
const smob_1 = require("smob");
const utils_1 = require("../../utils");
const utils_2 = require("../utils");
const utils_3 = require("./utils");
const constants_1 = require("../../constants");
// --------------------------------------------------
function buildReverseRecord(record) {
    const keys = Object.keys(record);
    const output = {};
    for (let i = 0; i < keys.length; i++) {
        output[record[keys[i]]] = keys[i];
    }
    return output;
}
function parseQueryFields(data, options) {
    var _a;
    options !== null && options !== void 0 ? options : (options = {});
    const defaultDomainFields = (0, utils_1.groupArrayByKeyPath)((0, utils_2.flattenParseAllowedOption)(options.default));
    const allowedDomainFields = (0, utils_1.groupArrayByKeyPath)((0, utils_2.flattenParseAllowedOption)(options.allowed));
    const domainFields = (0, smob_1.merge)({}, defaultDomainFields, allowedDomainFields);
    let keys = Object.keys(domainFields);
    // If it is an empty array nothing is allowed
    if ((typeof options.default !== 'undefined' ||
        typeof options.allowed !== 'undefined') && keys.length === 0) {
        return [];
    }
    const prototype = Object.prototype.toString.call(data);
    if (prototype !== '[object Object]' &&
        prototype !== '[object Array]' &&
        prototype !== '[object String]') {
        data = { [constants_1.DEFAULT_ID]: [] };
    }
    if (prototype === '[object String]') {
        data = { [constants_1.DEFAULT_ID]: data };
    }
    if (prototype === '[object Array]') {
        data = { [constants_1.DEFAULT_ID]: data };
    }
    (_a = options.mapping) !== null && _a !== void 0 ? _a : (options.mapping = {});
    const reverseMapping = buildReverseRecord(options.mapping);
    if (keys.length === 0) {
        keys = Object.keys(data);
    }
    const output = [];
    for (let i = 0; i < keys.length; i++) {
        const path = keys[i];
        if (!(0, utils_1.isFieldPathAllowedByRelations)({ path }, options.relations) &&
            path !== constants_1.DEFAULT_ID) {
            continue;
        }
        let fields = [];
        if ((0, utils_1.hasOwnProperty)(data, path)) {
            fields = (0, utils_3.parseFieldsInput)(data[path]);
        }
        else if ((0, utils_1.hasOwnProperty)(reverseMapping, path)) {
            if ((0, utils_1.hasOwnProperty)(data, reverseMapping[path])) {
                fields = (0, utils_3.parseFieldsInput)(data[reverseMapping[path]]);
            }
        }
        let transformed = {
            default: [],
            included: [],
            excluded: [],
        };
        if (fields.length > 0) {
            for (let j = 0; j < fields.length; j++) {
                fields[j] = (0, utils_1.applyMapping)((0, utils_1.buildFieldWithPath)({ name: fields[j], path }), options.mapping, true);
            }
            if ((0, utils_1.hasOwnProperty)(domainFields, path)) {
                fields = fields.filter((field) => domainFields[path].indexOf((0, utils_3.removeFieldInputOperator)(field)) !== -1);
            }
            else {
                fields = fields.filter((field) => (0, utils_3.isValidFieldName)((0, utils_3.removeFieldInputOperator)(field)));
            }
            transformed = (0, utils_3.transformFieldsInput)(fields);
        }
        if (transformed.default.length === 0 &&
            (0, utils_1.hasOwnProperty)(defaultDomainFields, path)) {
            transformed.default = defaultDomainFields[path];
        }
        if (transformed.included.length === 0 &&
            transformed.default.length === 0 &&
            (0, utils_1.hasOwnProperty)(allowedDomainFields, path)) {
            transformed.default = allowedDomainFields[path];
        }
        transformed.default = Array.from(new Set([
            ...transformed.default,
            ...transformed.included,
        ]));
        for (let j = 0; j < transformed.excluded.length; j++) {
            const index = transformed.default.indexOf(transformed.excluded[j]);
            if (index !== -1) {
                transformed.default.splice(index, 1);
            }
        }
        if (transformed.default.length > 0) {
            for (let j = 0; j < transformed.default.length; j++) {
                let destPath;
                if (path !== constants_1.DEFAULT_ID) {
                    destPath = path;
                }
                else if (options.defaultPath) {
                    destPath = options.defaultPath;
                }
                output.push(Object.assign({ key: transformed.default[j] }, (destPath ? { path: destPath } : {})));
            }
        }
    }
    return output;
}
exports.parseQueryFields = parseQueryFields;
//# sourceMappingURL=parse.js.map