"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const chai_1 = require("chai");
const shared_1 = require("../../shared");
const core_utils_1 = require("../../../../shared/core-utils");
const server_commands_1 = require("../../../../shared/server-commands");
describe('Save replay setting', function () {
    let servers = [];
    let liveVideoUUID;
    let ffmpegCommand;
    function createLiveWrapper(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (liveVideoUUID) {
                try {
                    yield servers[0].videos.remove({ id: liveVideoUUID });
                    yield (0, server_commands_1.waitJobs)(servers);
                }
                catch (_a) { }
            }
            const attributes = {
                channelId: servers[0].store.channel.id,
                privacy: 1,
                name: 'my super live',
                saveReplay: options.replay,
                permanentLive: options.permanent
            };
            const { uuid } = yield servers[0].live.create({ fields: attributes });
            return uuid;
        });
    }
    function publishLive(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            liveVideoUUID = yield createLiveWrapper(options);
            const ffmpegCommand = yield servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID });
            yield (0, server_commands_1.waitUntilLivePublishedOnAllServers)(servers, liveVideoUUID);
            const liveDetails = yield servers[0].videos.get({ id: liveVideoUUID });
            yield (0, server_commands_1.waitJobs)(servers);
            yield checkVideosExist(liveVideoUUID, true, 200);
            return { ffmpegCommand, liveDetails };
        });
    }
    function publishLiveAndDelete(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { ffmpegCommand, liveDetails } = yield publishLive(options);
            yield Promise.all([
                servers[0].videos.remove({ id: liveVideoUUID }),
                (0, server_commands_1.testFfmpegStreamError)(ffmpegCommand, true)
            ]);
            yield (0, server_commands_1.waitJobs)(servers);
            yield (0, core_utils_1.wait)(5000);
            yield (0, server_commands_1.waitJobs)(servers);
            return { liveDetails };
        });
    }
    function publishLiveAndBlacklist(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { ffmpegCommand, liveDetails } = yield publishLive(options);
            yield Promise.all([
                servers[0].blacklist.add({ videoId: liveVideoUUID, reason: 'bad live', unfederate: true }),
                (0, server_commands_1.testFfmpegStreamError)(ffmpegCommand, true)
            ]);
            yield (0, server_commands_1.waitJobs)(servers);
            yield (0, core_utils_1.wait)(5000);
            yield (0, server_commands_1.waitJobs)(servers);
            return { liveDetails };
        });
    }
    function checkVideosExist(videoId, existsInList, expectedStatus) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            for (const server of servers) {
                const length = existsInList ? 1 : 0;
                const { data, total } = yield server.videos.list();
                (0, chai_1.expect)(data).to.have.lengthOf(length);
                (0, chai_1.expect)(total).to.equal(length);
                if (expectedStatus) {
                    yield server.videos.get({ id: videoId, expectedStatus });
                }
            }
        });
    }
    function checkVideoState(videoId, state) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            for (const server of servers) {
                const video = yield server.videos.get({ id: videoId });
                (0, chai_1.expect)(video.state.id).to.equal(state);
            }
        });
    }
    before(function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(120000);
            servers = yield (0, server_commands_1.createMultipleServers)(2);
            yield (0, server_commands_1.setAccessTokensToServers)(servers);
            yield (0, server_commands_1.setDefaultVideoChannel)(servers);
            yield (0, server_commands_1.doubleFollow)(servers[0], servers[1]);
            yield servers[0].config.updateCustomSubConfig({
                newConfig: {
                    live: {
                        enabled: true,
                        allowReplay: true,
                        maxDuration: -1,
                        transcoding: {
                            enabled: false,
                            resolutions: server_commands_1.ConfigCommand.getCustomConfigResolutions(true)
                        }
                    }
                }
            });
        });
    });
    describe('With save replay disabled', function () {
        let sessionStartDateMin;
        let sessionStartDateMax;
        let sessionEndDateMin;
        it('Should correctly create and federate the "waiting for stream" live', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(20000);
                liveVideoUUID = yield createLiveWrapper({ permanent: false, replay: false });
                yield (0, server_commands_1.waitJobs)(servers);
                yield checkVideosExist(liveVideoUUID, false, 200);
                yield checkVideoState(liveVideoUUID, 4);
            });
        });
        it('Should correctly have updated the live and federated it when streaming in the live', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(30000);
                ffmpegCommand = yield servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID });
                sessionStartDateMin = new Date();
                yield (0, server_commands_1.waitUntilLivePublishedOnAllServers)(servers, liveVideoUUID);
                sessionStartDateMax = new Date();
                yield (0, server_commands_1.waitJobs)(servers);
                yield checkVideosExist(liveVideoUUID, true, 200);
                yield checkVideoState(liveVideoUUID, 1);
            });
        });
        it('Should correctly delete the video files after the stream ended', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(40000);
                sessionEndDateMin = new Date();
                yield (0, server_commands_1.stopFfmpeg)(ffmpegCommand);
                for (const server of servers) {
                    yield server.live.waitUntilEnded({ videoId: liveVideoUUID });
                }
                yield (0, server_commands_1.waitJobs)(servers);
                yield checkVideosExist(liveVideoUUID, false, 200);
                yield checkVideoState(liveVideoUUID, 5);
                yield (0, shared_1.checkLiveCleanup)({ server: servers[0], videoUUID: liveVideoUUID, permanent: false });
            });
        });
        it('Should have appropriate ended session', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                const { data, total } = yield servers[0].live.listSessions({ videoId: liveVideoUUID });
                (0, chai_1.expect)(total).to.equal(1);
                (0, chai_1.expect)(data).to.have.lengthOf(1);
                const session = data[0];
                const startDate = new Date(session.startDate);
                (0, chai_1.expect)(startDate).to.be.above(sessionStartDateMin);
                (0, chai_1.expect)(startDate).to.be.below(sessionStartDateMax);
                (0, chai_1.expect)(session.endDate).to.exist;
                (0, chai_1.expect)(new Date(session.endDate)).to.be.above(sessionEndDateMin);
                (0, chai_1.expect)(session.saveReplay).to.be.false;
                (0, chai_1.expect)(session.error).to.not.exist;
                (0, chai_1.expect)(session.replayVideo).to.not.exist;
            });
        });
        it('Should correctly terminate the stream on blacklist and delete the live', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(40000);
                yield publishLiveAndBlacklist({ permanent: false, replay: false });
                yield checkVideosExist(liveVideoUUID, false);
                yield servers[0].videos.get({ id: liveVideoUUID, expectedStatus: 401 });
                yield servers[1].videos.get({ id: liveVideoUUID, expectedStatus: 404 });
                yield (0, core_utils_1.wait)(5000);
                yield (0, server_commands_1.waitJobs)(servers);
                yield (0, shared_1.checkLiveCleanup)({ server: servers[0], videoUUID: liveVideoUUID, permanent: false });
            });
        });
        it('Should have blacklisted session error', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                const session = yield servers[0].live.findLatestSession({ videoId: liveVideoUUID });
                (0, chai_1.expect)(session.startDate).to.exist;
                (0, chai_1.expect)(session.endDate).to.exist;
                (0, chai_1.expect)(session.error).to.equal(5);
                (0, chai_1.expect)(session.replayVideo).to.not.exist;
            });
        });
        it('Should correctly terminate the stream on delete and delete the video', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(40000);
                yield publishLiveAndDelete({ permanent: false, replay: false });
                yield checkVideosExist(liveVideoUUID, false, 404);
                yield (0, shared_1.checkLiveCleanup)({ server: servers[0], videoUUID: liveVideoUUID, permanent: false });
            });
        });
    });
    describe('With save replay enabled on non permanent live', function () {
        it('Should correctly create and federate the "waiting for stream" live', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(20000);
                liveVideoUUID = yield createLiveWrapper({ permanent: false, replay: true });
                yield (0, server_commands_1.waitJobs)(servers);
                yield checkVideosExist(liveVideoUUID, false, 200);
                yield checkVideoState(liveVideoUUID, 4);
            });
        });
        it('Should correctly have updated the live and federated it when streaming in the live', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(20000);
                ffmpegCommand = yield servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID });
                yield (0, server_commands_1.waitUntilLivePublishedOnAllServers)(servers, liveVideoUUID);
                yield (0, server_commands_1.waitJobs)(servers);
                yield checkVideosExist(liveVideoUUID, true, 200);
                yield checkVideoState(liveVideoUUID, 1);
            });
        });
        it('Should correctly have saved the live and federated it after the streaming', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(30000);
                const session = yield servers[0].live.findLatestSession({ videoId: liveVideoUUID });
                (0, chai_1.expect)(session.endDate).to.not.exist;
                (0, chai_1.expect)(session.endingProcessed).to.be.false;
                (0, chai_1.expect)(session.saveReplay).to.be.true;
                yield (0, server_commands_1.stopFfmpeg)(ffmpegCommand);
                yield (0, server_commands_1.waitUntilLiveReplacedByReplayOnAllServers)(servers, liveVideoUUID);
                yield (0, server_commands_1.waitJobs)(servers);
                yield checkVideosExist(liveVideoUUID, true, 200);
                yield checkVideoState(liveVideoUUID, 1);
            });
        });
        it('Should find the replay live session', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                const session = yield servers[0].live.getReplaySession({ videoId: liveVideoUUID });
                (0, chai_1.expect)(session).to.exist;
                (0, chai_1.expect)(session.startDate).to.exist;
                (0, chai_1.expect)(session.endDate).to.exist;
                (0, chai_1.expect)(session.error).to.not.exist;
                (0, chai_1.expect)(session.saveReplay).to.be.true;
                (0, chai_1.expect)(session.endingProcessed).to.be.true;
                (0, chai_1.expect)(session.replayVideo).to.exist;
                (0, chai_1.expect)(session.replayVideo.id).to.exist;
                (0, chai_1.expect)(session.replayVideo.shortUUID).to.exist;
                (0, chai_1.expect)(session.replayVideo.uuid).to.equal(liveVideoUUID);
            });
        });
        it('Should update the saved live and correctly federate the updated attributes', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(30000);
                yield servers[0].videos.update({ id: liveVideoUUID, attributes: { name: 'video updated' } });
                yield (0, server_commands_1.waitJobs)(servers);
                for (const server of servers) {
                    const video = yield server.videos.get({ id: liveVideoUUID });
                    (0, chai_1.expect)(video.name).to.equal('video updated');
                    (0, chai_1.expect)(video.isLive).to.be.false;
                }
            });
        });
        it('Should have cleaned up the live files', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                yield (0, shared_1.checkLiveCleanup)({ server: servers[0], videoUUID: liveVideoUUID, permanent: false, savedResolutions: [720] });
            });
        });
        it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(120000);
                yield publishLiveAndBlacklist({ permanent: false, replay: true });
                yield checkVideosExist(liveVideoUUID, false);
                yield servers[0].videos.get({ id: liveVideoUUID, expectedStatus: 401 });
                yield servers[1].videos.get({ id: liveVideoUUID, expectedStatus: 404 });
                yield (0, core_utils_1.wait)(5000);
                yield (0, server_commands_1.waitJobs)(servers);
                yield (0, shared_1.checkLiveCleanup)({ server: servers[0], videoUUID: liveVideoUUID, permanent: false, savedResolutions: [720] });
            });
        });
        it('Should correctly terminate the stream on delete and delete the video', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(40000);
                yield publishLiveAndDelete({ permanent: false, replay: true });
                yield checkVideosExist(liveVideoUUID, false, 404);
                yield (0, shared_1.checkLiveCleanup)({ server: servers[0], videoUUID: liveVideoUUID, permanent: false });
            });
        });
    });
    describe('With save replay enabled on permanent live', function () {
        let lastReplayUUID;
        it('Should correctly create and federate the "waiting for stream" live', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(20000);
                liveVideoUUID = yield createLiveWrapper({ permanent: true, replay: true });
                yield (0, server_commands_1.waitJobs)(servers);
                yield checkVideosExist(liveVideoUUID, false, 200);
                yield checkVideoState(liveVideoUUID, 4);
            });
        });
        it('Should correctly have updated the live and federated it when streaming in the live', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(20000);
                ffmpegCommand = yield servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID });
                yield (0, server_commands_1.waitUntilLivePublishedOnAllServers)(servers, liveVideoUUID);
                yield (0, server_commands_1.waitJobs)(servers);
                yield checkVideosExist(liveVideoUUID, true, 200);
                yield checkVideoState(liveVideoUUID, 1);
            });
        });
        it('Should correctly have saved the live and federated it after the streaming', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(30000);
                const liveDetails = yield servers[0].videos.get({ id: liveVideoUUID });
                yield (0, server_commands_1.stopFfmpeg)(ffmpegCommand);
                yield (0, server_commands_1.waitUntilLiveWaitingOnAllServers)(servers, liveVideoUUID);
                yield (0, server_commands_1.waitJobs)(servers);
                const video = yield (0, server_commands_1.findExternalSavedVideo)(servers[0], liveDetails);
                (0, chai_1.expect)(video).to.exist;
                for (const server of servers) {
                    yield server.videos.get({ id: video.uuid });
                }
                lastReplayUUID = video.uuid;
            });
        });
        it('Should have appropriate ended session and replay live session', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                const { data, total } = yield servers[0].live.listSessions({ videoId: liveVideoUUID });
                (0, chai_1.expect)(total).to.equal(1);
                (0, chai_1.expect)(data).to.have.lengthOf(1);
                const sessionFromLive = data[0];
                const sessionFromReplay = yield servers[0].live.getReplaySession({ videoId: lastReplayUUID });
                for (const session of [sessionFromLive, sessionFromReplay]) {
                    (0, chai_1.expect)(session.startDate).to.exist;
                    (0, chai_1.expect)(session.endDate).to.exist;
                    (0, chai_1.expect)(session.error).to.not.exist;
                    (0, chai_1.expect)(session.replayVideo).to.exist;
                    (0, chai_1.expect)(session.replayVideo.id).to.exist;
                    (0, chai_1.expect)(session.replayVideo.shortUUID).to.exist;
                    (0, chai_1.expect)(session.replayVideo.uuid).to.equal(lastReplayUUID);
                }
            });
        });
        it('Should have cleaned up the live files', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                yield (0, shared_1.checkLiveCleanup)({ server: servers[0], videoUUID: liveVideoUUID, permanent: false });
            });
        });
        it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(120000);
                yield servers[0].videos.remove({ id: lastReplayUUID });
                const { liveDetails } = yield publishLiveAndBlacklist({ permanent: true, replay: true });
                const replay = yield (0, server_commands_1.findExternalSavedVideo)(servers[0], liveDetails);
                (0, chai_1.expect)(replay).to.exist;
                for (const videoId of [liveVideoUUID, replay.uuid]) {
                    yield checkVideosExist(videoId, false);
                    yield servers[0].videos.get({ id: videoId, expectedStatus: 401 });
                    yield servers[1].videos.get({ id: videoId, expectedStatus: 404 });
                }
                yield (0, shared_1.checkLiveCleanup)({ server: servers[0], videoUUID: liveVideoUUID, permanent: false });
            });
        });
        it('Should correctly terminate the stream on delete and not save the video', function () {
            return tslib_1.__awaiter(this, void 0, void 0, function* () {
                this.timeout(40000);
                const { liveDetails } = yield publishLiveAndDelete({ permanent: true, replay: true });
                const replay = yield (0, server_commands_1.findExternalSavedVideo)(servers[0], liveDetails);
                (0, chai_1.expect)(replay).to.not.exist;
                yield checkVideosExist(liveVideoUUID, false, 404);
                yield (0, shared_1.checkLiveCleanup)({ server: servers[0], videoUUID: liveVideoUUID, permanent: false });
            });
        });
    });
    after(function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield (0, server_commands_1.cleanupTests)(servers);
        });
    });
});
//# sourceMappingURL=live-save-replay.js.map