"use strict";
var VideoImportModel_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.VideoImportModel = void 0;
const tslib_1 = require("tslib");
const sequelize_1 = require("sequelize");
const sequelize_typescript_1 = require("sequelize-typescript");
const database_utils_1 = require("../../helpers/database-utils");
const video_imports_1 = require("../../helpers/custom-validators/video-imports");
const videos_1 = require("../../helpers/custom-validators/videos");
const constants_1 = require("../../initializers/constants");
const user_1 = require("../user/user");
const utils_1 = require("../utils");
const video_1 = require("./video");
const video_channel_sync_1 = require("./video-channel-sync");
const defaultVideoScope = () => {
    return video_1.VideoModel.scope([
        video_1.ScopeNames.WITH_ACCOUNT_DETAILS,
        video_1.ScopeNames.WITH_TAGS,
        video_1.ScopeNames.WITH_THUMBNAILS
    ]);
};
let VideoImportModel = VideoImportModel_1 = class VideoImportModel extends sequelize_typescript_1.Model {
    static deleteVideoIfFailed(instance, options) {
        if (instance.state === 3) {
            return (0, database_utils_1.afterCommitIfTransaction)(options.transaction, () => instance.Video.destroy());
        }
        return undefined;
    }
    static loadAndPopulateVideo(id) {
        return VideoImportModel_1.findByPk(id);
    }
    static listUserVideoImportsForApi(options) {
        const { userId, start, count, sort, targetUrl, videoChannelSyncId, search } = options;
        const where = { userId };
        const include = [
            {
                attributes: ['id'],
                model: user_1.UserModel.unscoped(),
                required: true
            },
            {
                model: video_channel_sync_1.VideoChannelSyncModel.unscoped(),
                required: false
            }
        ];
        if (targetUrl)
            where['targetUrl'] = targetUrl;
        if (videoChannelSyncId)
            where['videoChannelSyncId'] = videoChannelSyncId;
        if (search) {
            include.push({
                model: defaultVideoScope(),
                required: true,
                where: (0, utils_1.searchAttribute)(search, 'name')
            });
        }
        else {
            include.push({
                model: defaultVideoScope(),
                required: false
            });
        }
        const query = {
            distinct: true,
            include,
            offset: start,
            limit: count,
            order: (0, utils_1.getSort)(sort),
            where
        };
        return Promise.all([
            VideoImportModel_1.unscoped().count(query),
            VideoImportModel_1.findAll(query)
        ]).then(([total, data]) => ({ total, data }));
    }
    static urlAlreadyImported(channelId, targetUrl) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const element = yield VideoImportModel_1.unscoped().findOne({
                where: {
                    targetUrl,
                    state: {
                        [sequelize_1.Op.in]: [1, 6, 2]
                    }
                },
                include: [
                    {
                        model: video_1.VideoModel,
                        required: true,
                        where: {
                            channelId
                        }
                    }
                ]
            });
            return !!element;
        });
    }
    getTargetIdentifier() {
        return this.targetUrl || this.magnetUri || this.torrentName;
    }
    toFormattedJSON() {
        const videoFormatOptions = {
            completeDescription: true,
            additionalAttributes: { state: true, waitTranscoding: true, scheduledUpdate: true }
        };
        const video = this.Video
            ? Object.assign(this.Video.toFormattedJSON(videoFormatOptions), { tags: this.Video.Tags.map(t => t.name) })
            : undefined;
        const videoChannelSync = this.VideoChannelSync
            ? { id: this.VideoChannelSync.id, externalChannelUrl: this.VideoChannelSync.externalChannelUrl }
            : undefined;
        return {
            id: this.id,
            targetUrl: this.targetUrl,
            magnetUri: this.magnetUri,
            torrentName: this.torrentName,
            state: {
                id: this.state,
                label: VideoImportModel_1.getStateLabel(this.state)
            },
            error: this.error,
            updatedAt: this.updatedAt.toISOString(),
            createdAt: this.createdAt.toISOString(),
            video,
            videoChannelSync
        };
    }
    static getStateLabel(id) {
        return constants_1.VIDEO_IMPORT_STATES[id] || 'Unknown';
    }
};
tslib_1.__decorate([
    sequelize_typescript_1.CreatedAt,
    tslib_1.__metadata("design:type", Date)
], VideoImportModel.prototype, "createdAt", void 0);
tslib_1.__decorate([
    sequelize_typescript_1.UpdatedAt,
    tslib_1.__metadata("design:type", Date)
], VideoImportModel.prototype, "updatedAt", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.AllowNull)(true),
    (0, sequelize_typescript_1.Default)(null),
    (0, sequelize_typescript_1.Is)('VideoImportTargetUrl', value => (0, utils_1.throwIfNotValid)(value, video_imports_1.isVideoImportTargetUrlValid, 'targetUrl', true)),
    (0, sequelize_typescript_1.Column)(sequelize_typescript_1.DataType.STRING(constants_1.CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max)),
    tslib_1.__metadata("design:type", String)
], VideoImportModel.prototype, "targetUrl", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.AllowNull)(true),
    (0, sequelize_typescript_1.Default)(null),
    (0, sequelize_typescript_1.Is)('VideoImportMagnetUri', value => (0, utils_1.throwIfNotValid)(value, videos_1.isVideoMagnetUriValid, 'magnetUri', true)),
    (0, sequelize_typescript_1.Column)(sequelize_typescript_1.DataType.STRING(constants_1.CONSTRAINTS_FIELDS.VIDEO_IMPORTS.URL.max)),
    tslib_1.__metadata("design:type", String)
], VideoImportModel.prototype, "magnetUri", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.AllowNull)(true),
    (0, sequelize_typescript_1.Default)(null),
    (0, sequelize_typescript_1.Column)(sequelize_typescript_1.DataType.STRING(constants_1.CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_NAME.max)),
    tslib_1.__metadata("design:type", String)
], VideoImportModel.prototype, "torrentName", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.AllowNull)(false),
    (0, sequelize_typescript_1.Default)(null),
    (0, sequelize_typescript_1.Is)('VideoImportState', value => (0, utils_1.throwIfNotValid)(value, video_imports_1.isVideoImportStateValid, 'state')),
    sequelize_typescript_1.Column,
    tslib_1.__metadata("design:type", Number)
], VideoImportModel.prototype, "state", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.AllowNull)(true),
    (0, sequelize_typescript_1.Default)(null),
    (0, sequelize_typescript_1.Column)(sequelize_typescript_1.DataType.TEXT),
    tslib_1.__metadata("design:type", String)
], VideoImportModel.prototype, "error", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.ForeignKey)(() => user_1.UserModel),
    sequelize_typescript_1.Column,
    tslib_1.__metadata("design:type", Number)
], VideoImportModel.prototype, "userId", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.BelongsTo)(() => user_1.UserModel, {
        foreignKey: {
            allowNull: false
        },
        onDelete: 'cascade'
    }),
    tslib_1.__metadata("design:type", user_1.UserModel)
], VideoImportModel.prototype, "User", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.ForeignKey)(() => video_1.VideoModel),
    sequelize_typescript_1.Column,
    tslib_1.__metadata("design:type", Number)
], VideoImportModel.prototype, "videoId", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.BelongsTo)(() => video_1.VideoModel, {
        foreignKey: {
            allowNull: true
        },
        onDelete: 'set null'
    }),
    tslib_1.__metadata("design:type", video_1.VideoModel)
], VideoImportModel.prototype, "Video", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.ForeignKey)(() => video_channel_sync_1.VideoChannelSyncModel),
    sequelize_typescript_1.Column,
    tslib_1.__metadata("design:type", Number)
], VideoImportModel.prototype, "videoChannelSyncId", void 0);
tslib_1.__decorate([
    (0, sequelize_typescript_1.BelongsTo)(() => video_channel_sync_1.VideoChannelSyncModel, {
        foreignKey: {
            allowNull: true
        },
        onDelete: 'set null'
    }),
    tslib_1.__metadata("design:type", video_channel_sync_1.VideoChannelSyncModel)
], VideoImportModel.prototype, "VideoChannelSync", void 0);
tslib_1.__decorate([
    sequelize_typescript_1.AfterUpdate,
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [VideoImportModel, Object]),
    tslib_1.__metadata("design:returntype", void 0)
], VideoImportModel, "deleteVideoIfFailed", null);
VideoImportModel = VideoImportModel_1 = tslib_1.__decorate([
    (0, sequelize_typescript_1.DefaultScope)(() => ({
        include: [
            {
                model: user_1.UserModel.unscoped(),
                required: true
            },
            {
                model: defaultVideoScope(),
                required: false
            },
            {
                model: video_channel_sync_1.VideoChannelSyncModel.unscoped(),
                required: false
            }
        ]
    })),
    (0, sequelize_typescript_1.Table)({
        tableName: 'videoImport',
        indexes: [
            {
                fields: ['videoId'],
                unique: true
            },
            {
                fields: ['userId']
            }
        ]
    })
], VideoImportModel);
exports.VideoImportModel = VideoImportModel;
//# sourceMappingURL=video-import.js.map