import post from "../../../../services/note/create.js";
import { getApId } from "../../type.js";
import { fetchNote, resolveNote } from "../../models/note.js";
import { apLogger } from "../../logger.js";
import { extractDbHost } from "../../../../misc/convert-host.js";
import { getApLock } from "../../../../misc/app-lock.js";
import { parseAudience } from "../../audience.js";
import { StatusError } from "../../../../misc/fetch.js";
import { Notes } from "../../../../models/index.js";
import { shouldBlockInstance } from "../../../../misc/should-block-instance.js";
const logger = apLogger;
/**
 * Handle announcement activities
 */ export default async function(resolver, actor, activity, targetUri) {
    const uri = getApId(activity);
    if (actor.isSuspended) {
        return "skip: actor is suspended";
    }
    // Interrupt if you block the announcement destination
    if (await shouldBlockInstance(extractDbHost(uri))) return "skip: instance is blocked";
    const unlock = await getApLock(uri);
    try {
        // Check if something with the same URI is already registered
        const exist = await fetchNote(uri);
        if (exist) {
            return "skip: note exists";
        }
        // Resolve Announce target
        let renote;
        try {
            renote = await resolveNote(targetUri);
        } catch (e) {
            // Skip if target is 4xx
            if (e instanceof StatusError) {
                if (!e.isRetryable) {
                    logger.warn(`Ignored announce target ${targetUri} - ${e.statusCode}`);
                    return "skip: failed fetching note";
                }
                logger.warn(`Error in announce target ${targetUri} - ${e.statusCode || e}`);
            }
            throw e;
        }
        if (!await Notes.isVisibleForMe(renote, actor.id)) return "skip: invalid actor for this activity";
        logger.info(`Creating the (Re)Note: ${uri}`);
        const activityAudience = await parseAudience(actor, activity.to, activity.cc);
        await post(actor, {
            createdAt: activity.published ? new Date(activity.published) : null,
            renote,
            visibility: activityAudience.visibility,
            visibleUsers: activityAudience.visibleUsers,
            uri
        });
        return "ok";
    } finally{
        unlock();
    }
}
