"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.downloadRouter = void 0;
const tslib_1 = require("tslib");
const cors_1 = tslib_1.__importDefault(require("cors"));
const express_1 = tslib_1.__importDefault(require("express"));
const logger_1 = require("../helpers/logger");
const videos_torrent_cache_1 = require("../lib/files-cache/videos-torrent-cache");
const hooks_1 = require("../lib/plugins/hooks");
const video_path_manager_1 = require("../lib/video-path-manager");
const core_utils_1 = require("../../shared/core-utils");
const constants_1 = require("../initializers/constants");
const middlewares_1 = require("../middlewares");
const downloadRouter = express_1.default.Router();
exports.downloadRouter = downloadRouter;
downloadRouter.use((0, cors_1.default)());
downloadRouter.use(constants_1.STATIC_DOWNLOAD_PATHS.TORRENTS + ':filename', (0, middlewares_1.asyncMiddleware)(downloadTorrent));
downloadRouter.use(constants_1.STATIC_DOWNLOAD_PATHS.VIDEOS + ':id-:resolution([0-9]+).:extension', middlewares_1.optionalAuthenticate, (0, middlewares_1.asyncMiddleware)(middlewares_1.videosDownloadValidator), (0, middlewares_1.asyncMiddleware)(downloadVideoFile));
downloadRouter.use(constants_1.STATIC_DOWNLOAD_PATHS.HLS_VIDEOS + ':id-:resolution([0-9]+)-fragmented.:extension', middlewares_1.optionalAuthenticate, (0, middlewares_1.asyncMiddleware)(middlewares_1.videosDownloadValidator), (0, middlewares_1.asyncMiddleware)(downloadHLSVideoFile));
function downloadTorrent(req, res) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const result = yield videos_torrent_cache_1.VideosTorrentCache.Instance.getFilePath(req.params.filename);
        if (!result) {
            return res.fail({
                status: 404,
                message: 'Torrent file not found'
            });
        }
        const allowParameters = {
            req,
            res,
            torrentPath: result.path,
            downloadName: result.downloadName
        };
        const allowedResult = yield hooks_1.Hooks.wrapFun(isTorrentDownloadAllowed, allowParameters, 'filter:api.download.torrent.allowed.result');
        if (!checkAllowResult(res, allowParameters, allowedResult))
            return;
        return res.download(result.path, result.downloadName);
    });
}
function downloadVideoFile(req, res) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const video = res.locals.videoAll;
        const videoFile = getVideoFile(req, video.VideoFiles);
        if (!videoFile) {
            return res.fail({
                status: 404,
                message: 'Video file not found'
            });
        }
        const allowParameters = {
            req,
            res,
            video,
            videoFile
        };
        const allowedResult = yield hooks_1.Hooks.wrapFun(isVideoDownloadAllowed, allowParameters, 'filter:api.download.video.allowed.result');
        if (!checkAllowResult(res, allowParameters, allowedResult))
            return;
        if (videoFile.storage === 1) {
            return redirectToObjectStorage({ req, res, video, file: videoFile });
        }
        yield video_path_manager_1.VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(video), path => {
            const videoName = video.name.replace(/[/\\]/g, '_');
            const filename = `${videoName}-${videoFile.resolution}p${videoFile.extname}`;
            return res.download(path, filename);
        });
    });
}
function downloadHLSVideoFile(req, res) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const video = res.locals.videoAll;
        const streamingPlaylist = getHLSPlaylist(video);
        if (!streamingPlaylist)
            return res.status(404).end;
        const videoFile = getVideoFile(req, streamingPlaylist.VideoFiles);
        if (!videoFile) {
            return res.fail({
                status: 404,
                message: 'Video file not found'
            });
        }
        const allowParameters = {
            req,
            res,
            video,
            streamingPlaylist,
            videoFile
        };
        const allowedResult = yield hooks_1.Hooks.wrapFun(isVideoDownloadAllowed, allowParameters, 'filter:api.download.video.allowed.result');
        if (!checkAllowResult(res, allowParameters, allowedResult))
            return;
        if (videoFile.storage === 1) {
            return redirectToObjectStorage({ req, res, video, file: videoFile });
        }
        yield video_path_manager_1.VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(streamingPlaylist), path => {
            const filename = `${video.name}-${videoFile.resolution}p-${streamingPlaylist.getStringType()}${videoFile.extname}`;
            return res.download(path, filename);
        });
    });
}
function getVideoFile(req, files) {
    const resolution = (0, core_utils_1.forceNumber)(req.params.resolution);
    return files.find(f => f.resolution === resolution);
}
function getHLSPlaylist(video) {
    const playlist = video.VideoStreamingPlaylists.find(p => p.type === 1);
    if (!playlist)
        return undefined;
    return Object.assign(playlist, { Video: video });
}
function isTorrentDownloadAllowed(_object) {
    return { allowed: true };
}
function isVideoDownloadAllowed(_object) {
    return { allowed: true };
}
function checkAllowResult(res, allowParameters, result) {
    if (!result || result.allowed !== true) {
        logger_1.logger.info('Download is not allowed.', { result, allowParameters });
        res.fail({
            status: 403,
            message: (result === null || result === void 0 ? void 0 : result.errorMessage) || 'Refused download'
        });
        return false;
    }
    return true;
}
function redirectToObjectStorage(options) {
    const { req, res, video, file } = options;
    const baseUrl = file.getObjectStorageUrl(video);
    const url = video.hasPrivateStaticPath() && req.query.videoFileToken
        ? (0, core_utils_1.addQueryParams)(baseUrl, { videoFileToken: req.query.videoFileToken })
        : baseUrl;
    return res.redirect(url);
}
//# sourceMappingURL=download.js.map