"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LiveCommand = void 0;
const tslib_1 = require("tslib");
const fs_extra_1 = require("fs-extra");
const path_1 = require("path");
const core_utils_1 = require("../../core-utils");
const requests_1 = require("../requests");
const server_1 = require("../server");
const shared_1 = require("../shared");
const live_1 = require("./live");
class LiveCommand extends shared_1.AbstractCommand {
    get(options) {
        const path = '/api/v1/videos/live';
        return this.getRequestBody(Object.assign(Object.assign({}, options), { path: path + '/' + options.videoId, implicitToken: true, defaultExpectedStatus: 200 }));
    }
    listSessions(options) {
        const path = `/api/v1/videos/live/${options.videoId}/sessions`;
        return this.getRequestBody(Object.assign(Object.assign({}, options), { path, implicitToken: true, defaultExpectedStatus: 200 }));
    }
    findLatestSession(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { data: sessions } = yield this.listSessions(options);
            return sessions[sessions.length - 1];
        });
    }
    getReplaySession(options) {
        const path = `/api/v1/videos/${options.videoId}/live-session`;
        return this.getRequestBody(Object.assign(Object.assign({}, options), { path, implicitToken: true, defaultExpectedStatus: 200 }));
    }
    update(options) {
        const { videoId, fields } = options;
        const path = '/api/v1/videos/live';
        return this.putBodyRequest(Object.assign(Object.assign({}, options), { path: path + '/' + videoId, fields, implicitToken: true, defaultExpectedStatus: 204 }));
    }
    create(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { fields } = options;
            const path = '/api/v1/videos/live';
            const attaches = {};
            if (fields.thumbnailfile)
                attaches.thumbnailfile = fields.thumbnailfile;
            if (fields.previewfile)
                attaches.previewfile = fields.previewfile;
            const body = yield (0, requests_1.unwrapBody)(this.postUploadRequest(Object.assign(Object.assign({}, options), { path,
                attaches, fields: (0, core_utils_1.omit)(fields, ['thumbnailfile', 'previewfile']), implicitToken: true, defaultExpectedStatus: 200 })));
            return body.video;
        });
    }
    quickCreate(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { saveReplay, permanentLive, privacy } = options;
            const { uuid } = yield this.create(Object.assign(Object.assign({}, options), { fields: {
                    name: 'live',
                    permanentLive,
                    saveReplay,
                    channelId: this.server.store.channel.id,
                    privacy
                } }));
            const video = yield this.server.videos.getWithToken({ id: uuid });
            const live = yield this.get({ videoId: uuid });
            return { video, live };
        });
    }
    sendRTMPStreamInVideo(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { videoId, fixtureName, copyCodecs } = options;
            const videoLive = yield this.get({ videoId });
            return (0, live_1.sendRTMPStream)({ rtmpBaseUrl: videoLive.rtmpUrl, streamKey: videoLive.streamKey, fixtureName, copyCodecs });
        });
    }
    runAndTestStreamError(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const command = yield this.sendRTMPStreamInVideo(options);
            return (0, live_1.testFfmpegStreamError)(command, options.shouldHaveError);
        });
    }
    waitUntilPublished(options) {
        const { videoId } = options;
        return this.waitUntilState({ videoId, state: 1 });
    }
    waitUntilWaiting(options) {
        const { videoId } = options;
        return this.waitUntilState({ videoId, state: 4 });
    }
    waitUntilEnded(options) {
        const { videoId } = options;
        return this.waitUntilState({ videoId, state: 5 });
    }
    waitUntilSegmentGeneration(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { server, objectStorage, playlistNumber, segment, videoUUID } = options;
            const segmentName = `${playlistNumber}-00000${segment}.ts`;
            const baseUrl = objectStorage
                ? server_1.ObjectStorageCommand.getMockPlaylistBaseUrl() + 'hls'
                : server.url + '/static/streaming-playlists/hls';
            let error = true;
            while (error) {
                try {
                    yield this.getRawRequest(Object.assign(Object.assign({}, options), { url: `${baseUrl}/${videoUUID}/${segmentName}`, implicitToken: false, defaultExpectedStatus: 200 }));
                    const video = yield server.videos.get({ id: videoUUID });
                    const hlsPlaylist = video.streamingPlaylists[0];
                    const shaBody = yield server.streamingPlaylists.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url });
                    if (!shaBody[segmentName]) {
                        throw new Error('Segment SHA does not exist');
                    }
                    error = false;
                }
                catch (_a) {
                    error = true;
                    yield (0, core_utils_1.wait)(100);
                }
            }
        });
    }
    waitUntilReplacedByReplay(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let video;
            do {
                video = yield this.server.videos.getWithToken({ token: options.token, id: options.videoId });
                yield (0, core_utils_1.wait)(500);
            } while (video.isLive === true || video.state.id !== 1);
        });
    }
    getSegmentFile(options) {
        const { playlistNumber, segment, videoUUID, objectStorage = false } = options;
        const segmentName = `${playlistNumber}-00000${segment}.ts`;
        const baseUrl = objectStorage
            ? server_1.ObjectStorageCommand.getMockPlaylistBaseUrl()
            : `${this.server.url}/static/streaming-playlists/hls`;
        const url = `${baseUrl}/${videoUUID}/${segmentName}`;
        return this.getRawRequest(Object.assign(Object.assign({}, options), { url, implicitToken: false, defaultExpectedStatus: 200 }));
    }
    getPlaylistFile(options) {
        const { playlistName, videoUUID, objectStorage = false } = options;
        const baseUrl = objectStorage
            ? server_1.ObjectStorageCommand.getMockPlaylistBaseUrl()
            : `${this.server.url}/static/streaming-playlists/hls`;
        const url = `${baseUrl}/${videoUUID}/${playlistName}`;
        return this.getRawRequest(Object.assign(Object.assign({}, options), { url, implicitToken: false, defaultExpectedStatus: 200 }));
    }
    countPlaylists(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const basePath = this.server.servers.buildDirectory('streaming-playlists');
            const hlsPath = (0, path_1.join)(basePath, 'hls', options.videoUUID);
            const files = yield (0, fs_extra_1.readdir)(hlsPath);
            return files.filter(f => f.endsWith('.m3u8')).length;
        });
    }
    waitUntilState(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let video;
            do {
                video = yield this.server.videos.getWithToken({ token: options.token, id: options.videoId });
                yield (0, core_utils_1.wait)(500);
            } while (video.state.id !== options.state);
        });
    }
}
exports.LiveCommand = LiveCommand;
//# sourceMappingURL=live-command.js.map