import { getApIds } from "./type.js";
import Resolver from "./resolver.js";
import { resolvePerson } from "./models/person.js";
import { unique, concat } from "../../prelude/array.js";
import promiseLimit from "promise-limit";
import { RecursionLimiter } from "../../models/repositories/user-profile.js";
export async function parseAudience(actor, to, cc, resolver, limiter = new RecursionLimiter()) {
    const toGroups = groupingAudience(getApIds(to), actor);
    const ccGroups = groupingAudience(getApIds(cc), actor);
    const others = unique(concat([
        toGroups.other,
        ccGroups.other
    ]));
    resolver ??= new Resolver();
    const limit = promiseLimit(2);
    const mentionedUsers = (await Promise.all(others.map((id)=>limit(()=>resolvePerson(id, resolver, limiter).catch(()=>null))))).filter((x)=>x != null);
    if (toGroups.public.length > 0) {
        return {
            visibility: "public",
            mentionedUsers,
            visibleUsers: []
        };
    }
    if (ccGroups.public.length > 0) {
        return {
            visibility: "home",
            mentionedUsers,
            visibleUsers: []
        };
    }
    if (toGroups.followers.length > 0) {
        return {
            visibility: "followers",
            mentionedUsers,
            visibleUsers: []
        };
    }
    return {
        visibility: "specified",
        mentionedUsers,
        visibleUsers: mentionedUsers
    };
}
function groupingAudience(ids, actor) {
    const groups = {
        public: [],
        followers: [],
        other: []
    };
    for (const id of ids){
        if (isPublic(id)) {
            groups.public.push(id);
        } else if (isFollowers(id, actor)) {
            groups.followers.push(id);
        } else {
            groups.other.push(id);
        }
    }
    groups.other = unique(groups.other);
    return groups;
}
function isPublic(id) {
    return [
        "https://www.w3.org/ns/activitystreams#Public",
        "as:Public",
        "Public"
    ].includes(id);
}
function isFollowers(id, actor) {
    return id === (actor.followersUri || `${actor.uri}/followers`);
}
