"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.moveToNextState = exports.moveToFailedMoveToObjectStorageState = exports.moveToFailedTranscodingState = exports.moveToExternalStorageState = exports.buildNextVideoState = void 0;
const tslib_1 = require("tslib");
const database_utils_1 = require("../helpers/database-utils");
const logger_1 = require("../helpers/logger");
const config_1 = require("../initializers/config");
const database_1 = require("../initializers/database");
const video_1 = require("../models/video/video");
const video_job_info_1 = require("../models/video/video-job-info");
const videos_1 = require("./activitypub/videos");
const job_queue_1 = require("./job-queue");
const notifier_1 = require("./notifier");
const video_2 = require("./video");
function buildNextVideoState(currentState) {
    if (currentState === 1) {
        throw new Error('Video is already in its final state');
    }
    if (currentState !== 9 &&
        currentState !== 2 &&
        currentState !== 6 &&
        config_1.CONFIG.TRANSCODING.ENABLED) {
        return 2;
    }
    if (currentState !== 6 &&
        config_1.CONFIG.OBJECT_STORAGE.ENABLED) {
        return 6;
    }
    return 1;
}
exports.buildNextVideoState = buildNextVideoState;
function moveToNextState(options) {
    const { video, previousVideoState, isNewVideo = true } = options;
    return (0, database_utils_1.retryTransactionWrapper)(() => {
        return database_1.sequelizeTypescript.transaction((t) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            const videoDatabase = yield video_1.VideoModel.loadFull(video.uuid, t);
            if (!videoDatabase)
                return undefined;
            if (videoDatabase.state === 1) {
                return (0, videos_1.federateVideoIfNeeded)(videoDatabase, false, t);
            }
            const newState = buildNextVideoState(videoDatabase.state);
            if (newState === 1) {
                return moveToPublishedState({ video: videoDatabase, previousVideoState, isNewVideo, transaction: t });
            }
            if (newState === 6) {
                return moveToExternalStorageState({ video: videoDatabase, isNewVideo, transaction: t });
            }
        }));
    });
}
exports.moveToNextState = moveToNextState;
function moveToExternalStorageState(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { video, isNewVideo, transaction } = options;
        const videoJobInfo = yield video_job_info_1.VideoJobInfoModel.load(video.id, transaction);
        const pendingTranscode = (videoJobInfo === null || videoJobInfo === void 0 ? void 0 : videoJobInfo.pendingTranscode) || 0;
        if (pendingTranscode !== 0)
            return false;
        const previousVideoState = video.state;
        if (video.state !== 6) {
            yield video.setNewState(6, isNewVideo, transaction);
        }
        logger_1.logger.info('Creating external storage move job for video %s.', video.uuid, { tags: [video.uuid] });
        try {
            yield job_queue_1.JobQueue.Instance.createJob(yield (0, video_2.buildMoveToObjectStorageJob)({ video, previousVideoState, isNewVideo }));
            return true;
        }
        catch (err) {
            logger_1.logger.error('Cannot add move to object storage job', { err });
            return false;
        }
    });
}
exports.moveToExternalStorageState = moveToExternalStorageState;
function moveToFailedTranscodingState(video) {
    if (video.state === 7)
        return;
    return video.setNewState(7, false, undefined);
}
exports.moveToFailedTranscodingState = moveToFailedTranscodingState;
function moveToFailedMoveToObjectStorageState(video) {
    if (video.state === 8)
        return;
    return video.setNewState(8, false, undefined);
}
exports.moveToFailedMoveToObjectStorageState = moveToFailedMoveToObjectStorageState;
function moveToPublishedState(options) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const { video, isNewVideo, transaction, previousVideoState } = options;
        const previousState = previousVideoState !== null && previousVideoState !== void 0 ? previousVideoState : video.state;
        logger_1.logger.info('Publishing video %s.', video.uuid, { isNewVideo, previousState, tags: [video.uuid] });
        yield video.setNewState(1, isNewVideo, transaction);
        yield (0, videos_1.federateVideoIfNeeded)(video, isNewVideo, transaction);
        if (previousState === 9) {
            notifier_1.Notifier.Instance.notifyOfFinishedVideoStudioEdition(video);
            return;
        }
        if (isNewVideo) {
            notifier_1.Notifier.Instance.notifyOnNewVideoIfNeeded(video);
            if (previousState === 2) {
                notifier_1.Notifier.Instance.notifyOnVideoPublishedAfterTranscoding(video);
            }
        }
    });
}
//# sourceMappingURL=video-state.js.map