"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCachedVideoDuration = exports.addVideoJobsAfterUpdate = exports.getTranscodingJobPriority = exports.buildMoveToObjectStorageJob = exports.buildTranscodingJob = exports.buildOptimizeOrMergeAudioJob = exports.setVideoTags = exports.buildVideoThumbnailsFromReq = exports.buildLocalVideoFromReq = void 0;
const tslib_1 = require("tslib");
const memoizee_1 = tslib_1.__importDefault(require("memoizee"));
const config_1 = require("../initializers/config");
const constants_1 = require("../initializers/constants");
const tag_1 = require("../models/video/tag");
const video_1 = require("../models/video/video");
const video_job_info_1 = require("../models/video/video-job-info");
const job_queue_1 = require("./job-queue/job-queue");
const thumbnail_1 = require("./thumbnail");
const video_privacy_1 = require("./video-privacy");
function buildLocalVideoFromReq(videoInfo, channelId) {
    var _a, _b, _c;
    return {
        name: videoInfo.name,
        remote: false,
        category: videoInfo.category,
        licence: (_a = videoInfo.licence) !== null && _a !== void 0 ? _a : config_1.CONFIG.DEFAULTS.PUBLISH.LICENCE,
        language: videoInfo.language,
        commentsEnabled: (_b = videoInfo.commentsEnabled) !== null && _b !== void 0 ? _b : config_1.CONFIG.DEFAULTS.PUBLISH.COMMENTS_ENABLED,
        downloadEnabled: (_c = videoInfo.downloadEnabled) !== null && _c !== void 0 ? _c : config_1.CONFIG.DEFAULTS.PUBLISH.DOWNLOAD_ENABLED,
        waitTranscoding: videoInfo.waitTranscoding || false,
        nsfw: videoInfo.nsfw || false,
        description: videoInfo.description,
        support: videoInfo.support,
        privacy: videoInfo.privacy || 3,
        channelId,
        originallyPublishedAt: videoInfo.originallyPublishedAt
            ? new Date(videoInfo.originallyPublishedAt)
            : null
    };
}
exports.buildLocalVideoFromReq = buildLocalVideoFromReq;
function buildVideoThumbnailsFromReq(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { video, files, fallback, automaticallyGenerated } = options;
        const promises = [
            {
                type: 1,
                fieldName: 'thumbnailfile'
            },
            {
                type: 2,
                fieldName: 'previewfile'
            }
        ].map(p => {
            const fields = files === null || files === void 0 ? void 0 : files[p.fieldName];
            if (fields) {
                return (0, thumbnail_1.updateVideoMiniatureFromExisting)({
                    inputPath: fields[0].path,
                    video,
                    type: p.type,
                    automaticallyGenerated: automaticallyGenerated || false
                });
            }
            return fallback(p.type);
        });
        return Promise.all(promises);
    });
}
exports.buildVideoThumbnailsFromReq = buildVideoThumbnailsFromReq;
function setVideoTags(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { video, tags, transaction } = options;
        const internalTags = tags || [];
        const tagInstances = yield tag_1.TagModel.findOrCreateTags(internalTags, transaction);
        yield video.$set('Tags', tagInstances, { transaction });
        video.Tags = tagInstances;
    });
}
exports.setVideoTags = setVideoTags;
function buildOptimizeOrMergeAudioJob(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { video, videoFile, user, isNewVideo } = options;
        let payload;
        if (videoFile.isAudio()) {
            payload = {
                type: 'merge-audio-to-webtorrent',
                resolution: constants_1.DEFAULT_AUDIO_RESOLUTION,
                videoUUID: video.uuid,
                createHLSIfNeeded: true,
                isNewVideo
            };
        }
        else {
            payload = {
                type: 'optimize-to-webtorrent',
                videoUUID: video.uuid,
                isNewVideo
            };
        }
        yield video_job_info_1.VideoJobInfoModel.increaseOrCreate(payload.videoUUID, 'pendingTranscode');
        return {
            type: 'video-transcoding',
            priority: yield getTranscodingJobPriority(user),
            payload
        };
    });
}
exports.buildOptimizeOrMergeAudioJob = buildOptimizeOrMergeAudioJob;
function buildTranscodingJob(payload, options = {}) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        yield video_job_info_1.VideoJobInfoModel.increaseOrCreate(payload.videoUUID, 'pendingTranscode');
        return Object.assign({ type: 'video-transcoding', payload }, options);
    });
}
exports.buildTranscodingJob = buildTranscodingJob;
function getTranscodingJobPriority(user) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const now = new Date();
        const lastWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7);
        const videoUploadedByUser = yield video_1.VideoModel.countVideosUploadedByUserSince(user.id, lastWeek);
        return constants_1.JOB_PRIORITY.TRANSCODING + videoUploadedByUser;
    });
}
exports.getTranscodingJobPriority = getTranscodingJobPriority;
function buildMoveToObjectStorageJob(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { video, previousVideoState, isNewVideo = true } = options;
        yield video_job_info_1.VideoJobInfoModel.increaseOrCreate(video.uuid, 'pendingMove');
        return {
            type: 'move-to-object-storage',
            payload: {
                videoUUID: video.uuid,
                isNewVideo,
                previousVideoState
            }
        };
    });
}
exports.buildMoveToObjectStorageJob = buildMoveToObjectStorageJob;
function getVideoDuration(videoId) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const video = yield video_1.VideoModel.load(videoId);
        const duration = video.isLive
            ? undefined
            : video.duration;
        return { duration, isLive: video.isLive };
    });
}
const getCachedVideoDuration = (0, memoizee_1.default)(getVideoDuration, {
    promise: true,
    max: constants_1.MEMOIZE_LENGTH.VIDEO_DURATION,
    maxAge: constants_1.MEMOIZE_TTL.VIDEO_DURATION
});
exports.getCachedVideoDuration = getCachedVideoDuration;
function addVideoJobsAfterUpdate(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { video, nameChanged, oldPrivacy, isNewVideo } = options;
        const jobs = [];
        const filePathChanged = yield (0, video_privacy_1.moveFilesIfPrivacyChanged)(video, oldPrivacy);
        if (!video.isLive && (nameChanged || filePathChanged)) {
            for (const file of (video.VideoFiles || [])) {
                const payload = { action: 'update-metadata', videoId: video.id, videoFileId: file.id };
                jobs.push({ type: 'manage-video-torrent', payload });
            }
            const hls = video.getHLSPlaylist();
            for (const file of ((hls === null || hls === void 0 ? void 0 : hls.VideoFiles) || [])) {
                const payload = { action: 'update-metadata', streamingPlaylistId: hls.id, videoFileId: file.id };
                jobs.push({ type: 'manage-video-torrent', payload });
            }
        }
        jobs.push({
            type: 'federate-video',
            payload: {
                videoUUID: video.uuid,
                isNewVideo
            }
        });
        const wasConfidentialVideo = new Set([3, 2, 4]).has(oldPrivacy);
        if (wasConfidentialVideo) {
            jobs.push({
                type: 'notify',
                payload: {
                    action: 'new-video',
                    videoUUID: video.uuid
                }
            });
        }
        return job_queue_1.JobQueue.Instance.createSequentialJobFlow(...jobs);
    });
}
exports.addVideoJobsAfterUpdate = addVideoJobsAfterUpdate;
//# sourceMappingURL=video.js.map