"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEntityFollowersGroupId = getEntityFollowersGroupId;
exports.isUserFollowing = isUserFollowing;
exports.followEntity = followEntity;
exports.unfollowEntity = unfollowEntity;
const arcgis_rest_portal_1 = require("@esri/arcgis-rest-portal");
const fetchHubEntity_1 = require("../core/fetchHubEntity");
/**
 * Get the entity's followers group id
 * @param entityId entity id
 * @param entityType entity type
 * @param context context used to support fetchHubEntity so it has access
 * to different types of request options based on the entity type
 * @returns {string} entity's followers group id
 */
async function getEntityFollowersGroupId(entityId, entityType, context) {
    // entity's type is IWithFollowers as we only want to accept hub entities
    // backed by item entities which extend IWithFollowers
    let entity;
    try {
        entity = (await (0, fetchHubEntity_1.fetchHubEntity)(entityType, entityId, context));
        return entity.followersGroupId;
    }
    catch (e) {
        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
        throw new Error(`Error fetching entity followers group ID: ${e}`);
    }
}
/**
 * Whether the user is currently following the entity
 * @param entityOrId hub entity or entity id, type is IWithFollowers
 * as we only want to accept hub entities backed by item entities which
 * extend IWithFollowers
 * @param user
 * @param entityType
 * @param context
 * @returns {boolean}
 */
async function isUserFollowing(entityOrId, user, entityType, context) {
    // get the entity's followers group id
    let groupId;
    if (typeof entityOrId === "string") {
        groupId = await getEntityFollowersGroupId(entityOrId, entityType, context);
    }
    else {
        groupId = entityOrId.followersGroupId;
    }
    // looks through the users group list and find the same group
    const group = user.groups.find((g) => g.id === groupId);
    return !!group;
}
/**
 * Follow an entity
 * @param entityId entity id
 * @param user user who attempts to follow the entity
 * @param entityType optional if entityOrId is a string
 * @param context optional if entityOrId is a string
 * @returns promise that resolves { success: true, username: user.username }
 * or rejects with an error
 */
async function followEntity(entityId, user, entityType, context) {
    const isFollowing = await isUserFollowing(entityId, user, entityType, context);
    // don't update if user is already following
    if (isFollowing) {
        return Promise.reject("User is already following this entity.");
    }
    const groupId = await getEntityFollowersGroupId(entityId, entityType, context);
    try {
        await (0, arcgis_rest_portal_1.joinGroup)({
            id: groupId,
            authentication: context.hubRequestOptions.authentication,
        });
        // successfully joined the group
        return { success: true, username: user.username };
    }
    catch (error) {
        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
        throw new Error(`Error joining group: ${error}`);
    }
}
/**
 * Unfollow an entity
 * @param entityId entity id
 * @param user user who attempts to unfollow the entity
 * @param entityType optional if entityOrId is a string
 * @param context optional if entityOrId is a string
 * @returns promise that resolves { success: true, username: user.username } or
 * rejects with an error
 */
async function unfollowEntity(entityId, user, entityType, context) {
    const isFollowing = await isUserFollowing(entityId, user, entityType, context);
    // don't update if user is not following
    if (!isFollowing) {
        return Promise.reject("User is not following this entity.");
    }
    const groupId = await getEntityFollowersGroupId(entityId, entityType, context);
    try {
        await (0, arcgis_rest_portal_1.leaveGroup)({
            id: groupId,
            authentication: context.hubRequestOptions.authentication,
        });
        // successfully left the group
        return { success: true, username: user.username };
    }
    catch (error) {
        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
        throw new Error(`Error leaving group: ${error}`);
    }
}
//# sourceMappingURL=follow.js.map