"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.processDeleteActivity = void 0;
const tslib_1 = require("tslib");
const database_utils_1 = require("../../../helpers/database-utils");
const logger_1 = require("../../../helpers/logger");
const database_1 = require("../../../initializers/database");
const actor_1 = require("../../../models/actor/actor");
const video_1 = require("../../../models/video/video");
const video_comment_1 = require("../../../models/video/video-comment");
const video_playlist_1 = require("../../../models/video/video-playlist");
const send_utils_1 = require("../send/shared/send-utils");
function processDeleteActivity(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { activity, byActor } = options;
        const objectUrl = typeof activity.object === 'string' ? activity.object : activity.object.id;
        if (activity.actor === objectUrl) {
            const byActorFull = yield actor_1.ActorModel.loadByUrlAndPopulateAccountAndChannel(byActor.url);
            if (byActorFull.type === 'Person') {
                if (!byActorFull.Account)
                    throw new Error('Actor ' + byActorFull.url + ' is a person but we cannot find it in database.');
                const accountToDelete = byActorFull.Account;
                accountToDelete.Actor = byActorFull;
                return (0, database_utils_1.retryTransactionWrapper)(processDeleteAccount, accountToDelete);
            }
            else if (byActorFull.type === 'Group') {
                if (!byActorFull.VideoChannel)
                    throw new Error('Actor ' + byActorFull.url + ' is a group but we cannot find it in database.');
                const channelToDelete = byActorFull.VideoChannel;
                channelToDelete.Actor = byActorFull;
                return (0, database_utils_1.retryTransactionWrapper)(processDeleteVideoChannel, channelToDelete);
            }
        }
        {
            const videoCommentInstance = yield video_comment_1.VideoCommentModel.loadByUrlAndPopulateAccountAndVideo(objectUrl);
            if (videoCommentInstance) {
                return (0, database_utils_1.retryTransactionWrapper)(processDeleteVideoComment, byActor, videoCommentInstance, activity);
            }
        }
        {
            const videoInstance = yield video_1.VideoModel.loadByUrlAndPopulateAccount(objectUrl);
            if (videoInstance) {
                if (videoInstance.isOwned())
                    throw new Error(`Remote instance cannot delete owned video ${videoInstance.url}.`);
                return (0, database_utils_1.retryTransactionWrapper)(processDeleteVideo, byActor, videoInstance);
            }
        }
        {
            const videoPlaylist = yield video_playlist_1.VideoPlaylistModel.loadByUrlAndPopulateAccount(objectUrl);
            if (videoPlaylist) {
                if (videoPlaylist.isOwned())
                    throw new Error(`Remote instance cannot delete owned playlist ${videoPlaylist.url}.`);
                return (0, database_utils_1.retryTransactionWrapper)(processDeleteVideoPlaylist, byActor, videoPlaylist);
            }
        }
        return undefined;
    });
}
exports.processDeleteActivity = processDeleteActivity;
function processDeleteVideo(actor, videoToDelete) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        logger_1.logger.debug('Removing remote video "%s".', videoToDelete.uuid);
        yield database_1.sequelizeTypescript.transaction((t) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (videoToDelete.VideoChannel.Account.Actor.id !== actor.id) {
                throw new Error('Account ' + actor.url + ' does not own video channel ' + videoToDelete.VideoChannel.Actor.url);
            }
            yield videoToDelete.destroy({ transaction: t });
        }));
        logger_1.logger.info('Remote video with uuid %s removed.', videoToDelete.uuid);
    });
}
function processDeleteVideoPlaylist(actor, playlistToDelete) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        logger_1.logger.debug('Removing remote video playlist "%s".', playlistToDelete.uuid);
        yield database_1.sequelizeTypescript.transaction((t) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (playlistToDelete.OwnerAccount.Actor.id !== actor.id) {
                throw new Error('Account ' + actor.url + ' does not own video playlist ' + playlistToDelete.url);
            }
            yield playlistToDelete.destroy({ transaction: t });
        }));
        logger_1.logger.info('Remote video playlist with uuid %s removed.', playlistToDelete.uuid);
    });
}
function processDeleteAccount(accountToRemove) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        logger_1.logger.debug('Removing remote account "%s".', accountToRemove.Actor.url);
        yield database_1.sequelizeTypescript.transaction((t) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield accountToRemove.destroy({ transaction: t });
        }));
        logger_1.logger.info('Remote account %s removed.', accountToRemove.Actor.url);
    });
}
function processDeleteVideoChannel(videoChannelToRemove) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        logger_1.logger.debug('Removing remote video channel "%s".', videoChannelToRemove.Actor.url);
        yield database_1.sequelizeTypescript.transaction((t) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield videoChannelToRemove.destroy({ transaction: t });
        }));
        logger_1.logger.info('Remote video channel %s removed.', videoChannelToRemove.Actor.url);
    });
}
function processDeleteVideoComment(byActor, videoComment, activity) {
    if (videoComment.isDeleted())
        return Promise.resolve();
    logger_1.logger.debug('Removing remote video comment "%s".', videoComment.url);
    return database_1.sequelizeTypescript.transaction((t) => tslib_1.__awaiter(this, void 0, void 0, function* () {
        if (byActor.Account.id !== videoComment.Account.id && byActor.Account.id !== videoComment.Video.VideoChannel.accountId) {
            throw new Error(`Account ${byActor.url} does not own video comment ${videoComment.url} or video ${videoComment.Video.url}`);
        }
        videoComment.markAsDeleted();
        yield videoComment.save({ transaction: t });
        if (videoComment.Video.isOwned()) {
            const exceptions = [byActor];
            yield (0, send_utils_1.forwardVideoRelatedActivity)(activity, t, exceptions, videoComment.Video);
        }
        logger_1.logger.info('Remote video comment %s removed.', videoComment.url);
    }));
}
//# sourceMappingURL=process-delete.js.map