"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAssociationStats = void 0;
const getTypeFromEntity_1 = require("../core/getTypeFromEntity");
const hubSearch_1 = require("../search/hubSearch");
const getAssociatedEntitiesQuery_1 = require("./getAssociatedEntitiesQuery");
const getPendingEntitiesQuery_1 = require("./getPendingEntitiesQuery");
const getRequestingEntitiesQuery_1 = require("./getRequestingEntitiesQuery");
const getAssociationHierarchy_1 = require("./internal/getAssociationHierarchy");
const isAssociationSupported_1 = require("./internal/isAssociationSupported");
/**
 * get Entity A's association stats with Entity B:
 *
 * 1. associated: the number of Entity B's that Entity A
 * is associated with
 *
 * 2. pending: the number of outgoing requests Entity A
 * has sent to Entity B
 *
 * 3. requesting: the number of incoming requests Entity A
 * has received from Entity B
 *
 * 4a. included: if Entity A is the parent, the number of
 * Entity B's it has included in its association group
 *
 * 4b. referenced: if Entity A is the child, the number of
 * Entity B's it has referenced (via typeKeyword)
 *
 * @param entity - Hub entity
 * @param associationType - entity type to query for
 * @param context - contextual auth and portal information
 * @returns
 */
const getAssociationStats = async (entity, associationType, context) => {
    let stats;
    const entityType = (0, getTypeFromEntity_1.getTypeFromEntity)(entity);
    const isSupported = (0, isAssociationSupported_1.isAssociationSupported)(entityType, associationType);
    if (!isSupported) {
        throw new Error(`getAssociationStats: Association between ${entityType} and ${associationType} is not supported.`);
    }
    const associationHierarchy = (0, getAssociationHierarchy_1.getAssociationHierarchy)(entityType);
    const isParent = associationHierarchy.children.includes(associationType);
    stats = Object.assign({ associated: 0, pending: 0, requesting: 0 }, (isParent ? { included: 0 } : { referenced: 0 }));
    try {
        const queries = await Promise.all([
            (0, getAssociatedEntitiesQuery_1.getAssociatedEntitiesQuery)(entity, associationType, context),
            (0, getPendingEntitiesQuery_1.getPendingEntitiesQuery)(entity, associationType, context),
            (0, getRequestingEntitiesQuery_1.getRequestingEntitiesQuery)(entity, associationType, context),
        ]);
        const [{ total: associated }, { total: pending }, { total: requesting }] = await Promise.all(queries.map(async (query) => {
            try {
                return await (0, hubSearch_1.hubSearch)(query, {
                    requestOptions: context.hubRequestOptions,
                });
            }
            catch (_error) {
                return { total: 0 };
            }
        }));
        stats = Object.assign({ associated,
            pending,
            requesting }, (isParent
            ? { included: associated + pending }
            : { referenced: associated + pending }));
    }
    catch (_error) {
        return stats;
    }
    return stats;
};
exports.getAssociationStats = getAssociationStats;
//# sourceMappingURL=getAssociationStats.js.map