"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getIncludesDoesNotReferenceQuery = void 0;
const arcgis_rest_portal_1 = require("@esri/arcgis-rest-portal");
const getTypesFromEntityType_1 = require("../../core/getTypesFromEntityType");
const get_prop_1 = require("../../objects/get-prop");
const combineQueries_1 = require("../../search/combineQueries");
const getTypeWithoutKeywordQuery_1 = require("./getTypeWithoutKeywordQuery");
const getTypeByIdsQuery_1 = require("./getTypeByIdsQuery");
const getTypeFromEntity_1 = require("../../core/getTypeFromEntity");
const getIdsFromKeywords_1 = require("./getIdsFromKeywords");
const getIdsFromAssociationGroups_1 = require("./getIdsFromAssociationGroups");
/**
 * builds a query that will return entities that are
 * "included" but NOT "referenced"
 *
 * @param entity - Hub entity
 * @param associationType - entity type to query for
 * @param isParent - whether the provided Hub entity is the parent in the association relationship
 * @param context - contextual auth and portal information
 * @returns {IQuery}
 */
const getIncludesDoesNotReferenceQuery = async (entity, associationType, isParent, context) => {
    if (isParent) {
        /**
         * 1. build query that returns child entities WITHOUT a
         * typeKeyword reference to the parent
         */
        const parentType = (0, getTypeFromEntity_1.getTypeFromEntity)(entity);
        const referencedQuery = (0, getTypeWithoutKeywordQuery_1.getTypeWithoutKeywordQuery)((0, getTypesFromEntityType_1.getTypesFromEntityType)(associationType), `ref|${parentType}|${entity.id}`);
        /** 2. grab the parent entity's association query */
        const includedQuery = (0, get_prop_1.getProp)(entity, "associations.rules.query");
        /** 3. combine queries - will remove null/undefined entries */
        return (0, combineQueries_1.combineQueries)([referencedQuery, includedQuery]);
    }
    else {
        /** 1. fetch the groups a child has been shared with */
        const { admin, member, other } = await (0, arcgis_rest_portal_1.getItemGroups)(entity.id, context.requestOptions);
        const groupsChildIsSharedWith = [...admin, ...member, ...other];
        /**
         * 2. filter the child's groups down to association groups
         * (by checking if they have a typeKeyword of the form
         * <associationType>|<id>) and extract parent ids
         */
        const parentIdsThatIncludeChild = (0, getIdsFromAssociationGroups_1.getIdsFromAssociationGroups)(groupsChildIsSharedWith, associationType);
        /**
         * 3. iterate over the child's typeKeywords and grab the parent
         * ids it references (typeKeyword = <associationType>|<id>)
         */
        const parentIdsChildReferences = (0, getIdsFromKeywords_1.getIdsFromKeywords)(entity, associationType);
        /**
         * 4. filter the parent ids down to those that include the
         * child, but that the child does NOT reference
         */
        const parentIds = parentIdsThatIncludeChild.filter((id) => !parentIdsChildReferences.includes(id));
        /** 5. return a query for the filtered parent ids */
        const type = (0, getTypesFromEntityType_1.getTypesFromEntityType)(associationType);
        return parentIds.length ? (0, getTypeByIdsQuery_1.getTypeByIdsQuery)(type, parentIds) : null;
    }
};
exports.getIncludesDoesNotReferenceQuery = getIncludesDoesNotReferenceQuery;
//# sourceMappingURL=getIncludesDoesNotReferenceQuery.js.map