"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildActorInstance = exports.downloadImageFromWorker = exports.deleteLocalActorImageFile = exports.downloadActorImageFromWorker = exports.findAvailableLocalActorName = exports.updateLocalActorImageFiles = exports.actorImagePathUnsafeCache = void 0;
const tslib_1 = require("tslib");
const fs_extra_1 = require("fs-extra");
const lru_cache_1 = tslib_1.__importDefault(require("lru-cache"));
const path_1 = require("path");
const actor_1 = require("../models/actor/actor");
const core_utils_1 = require("../../shared/core-utils");
const extra_utils_1 = require("../../shared/extra-utils");
const database_utils_1 = require("../helpers/database-utils");
const config_1 = require("../initializers/config");
const constants_1 = require("../initializers/constants");
const database_1 = require("../initializers/database");
const actors_1 = require("./activitypub/actors");
const send_1 = require("./activitypub/send");
const parent_process_1 = require("./worker/parent-process");
Object.defineProperty(exports, "downloadImageFromWorker", { enumerable: true, get: function () { return parent_process_1.downloadImageFromWorker; } });
function buildActorInstance(type, url, preferredUsername) {
    return new actor_1.ActorModel({
        type,
        url,
        preferredUsername,
        publicKey: null,
        privateKey: null,
        followersCount: 0,
        followingCount: 0,
        inboxUrl: url + '/inbox',
        outboxUrl: url + '/outbox',
        sharedInboxUrl: constants_1.WEBSERVER.URL + '/inbox',
        followersUrl: url + '/followers',
        followingUrl: url + '/following'
    });
}
exports.buildActorInstance = buildActorInstance;
function updateLocalActorImageFiles(accountOrChannel, imagePhysicalFile, type) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const processImageSize = (imageSize) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            const extension = (0, core_utils_1.getLowercaseExtension)(imagePhysicalFile.filename);
            const imageName = (0, extra_utils_1.buildUUID)() + extension;
            const destination = (0, path_1.join)(config_1.CONFIG.STORAGE.ACTOR_IMAGES, imageName);
            yield (0, parent_process_1.processImageFromWorker)({ path: imagePhysicalFile.path, destination, newSize: imageSize, keepOriginal: true });
            return {
                imageName,
                imageSize
            };
        });
        const processedImages = yield Promise.all(constants_1.ACTOR_IMAGES_SIZE[type].map(processImageSize));
        yield (0, fs_extra_1.remove)(imagePhysicalFile.path);
        return (0, database_utils_1.retryTransactionWrapper)(() => database_1.sequelizeTypescript.transaction((t) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            const actorImagesInfo = processedImages.map(({ imageName, imageSize }) => ({
                name: imageName,
                fileUrl: null,
                height: imageSize.height,
                width: imageSize.width,
                onDisk: true
            }));
            const updatedActor = yield (0, actors_1.updateActorImages)(accountOrChannel.Actor, type, actorImagesInfo, t);
            yield updatedActor.save({ transaction: t });
            yield (0, send_1.sendUpdateActor)(accountOrChannel, t);
            return type === 1
                ? updatedActor.Avatars
                : updatedActor.Banners;
        })));
    });
}
exports.updateLocalActorImageFiles = updateLocalActorImageFiles;
function deleteLocalActorImageFile(accountOrChannel, type) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        return (0, database_utils_1.retryTransactionWrapper)(() => {
            return database_1.sequelizeTypescript.transaction((t) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                const updatedActor = yield (0, actors_1.deleteActorImages)(accountOrChannel.Actor, type, t);
                yield updatedActor.save({ transaction: t });
                yield (0, send_1.sendUpdateActor)(accountOrChannel, t);
                return updatedActor.Avatars;
            }));
        });
    });
}
exports.deleteLocalActorImageFile = deleteLocalActorImageFile;
function findAvailableLocalActorName(baseActorName, transaction) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        let actor = yield actor_1.ActorModel.loadLocalByName(baseActorName, transaction);
        if (!actor)
            return baseActorName;
        for (let i = 1; i < 30; i++) {
            const name = `${baseActorName}-${i}`;
            actor = yield actor_1.ActorModel.loadLocalByName(name, transaction);
            if (!actor)
                return name;
        }
        throw new Error('Cannot find available actor local name (too much iterations).');
    });
}
exports.findAvailableLocalActorName = findAvailableLocalActorName;
function downloadActorImageFromWorker(options) {
    const downloaderOptions = {
        url: options.fileUrl,
        destDir: config_1.CONFIG.STORAGE.ACTOR_IMAGES,
        destName: options.filename,
        size: options.size
    };
    return (0, parent_process_1.downloadImageFromWorker)(downloaderOptions);
}
exports.downloadActorImageFromWorker = downloadActorImageFromWorker;
const actorImagePathUnsafeCache = new lru_cache_1.default({ max: constants_1.LRU_CACHE.ACTOR_IMAGE_STATIC.MAX_SIZE });
exports.actorImagePathUnsafeCache = actorImagePathUnsafeCache;
//# sourceMappingURL=local-actor.js.map