"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntegrityRepository = void 0;
const common_1 = require("@nestjs/common");
const kysely_1 = require("kysely");
const nestjs_kysely_1 = require("nestjs-kysely");
const decorators_1 = require("../decorators");
const enum_1 = require("../enum");
let IntegrityRepository = class IntegrityRepository {
    db;
    constructor(db) {
        this.db = db;
    }
    create(dto) {
        return this.db
            .insertInto('integrity_report')
            .values(dto)
            .onConflict((oc) => oc.columns(['path', 'type']).doUpdateSet({
            assetId: (eb) => eb.ref('excluded.assetId'),
            fileAssetId: (eb) => eb.ref('excluded.fileAssetId'),
        }))
            .returningAll()
            .executeTakeFirstOrThrow();
    }
    getById(id) {
        return this.db
            .selectFrom('integrity_report')
            .selectAll('integrity_report')
            .where('id', '=', id)
            .executeTakeFirstOrThrow();
    }
    async getIntegrityReportSummary() {
        const counts = await this.db
            .selectFrom('integrity_report')
            .select(['type', this.db.fn.countAll().as('count')])
            .groupBy('type')
            .execute();
        return Object.fromEntries(Object.values(enum_1.IntegrityReport).map((type) => [type, counts.find((count) => count.type === type)?.count || 0]));
    }
    async getIntegrityReport(pagination, type) {
        const items = await this.db
            .selectFrom('integrity_report')
            .select(['id', 'type', 'path', 'assetId', 'fileAssetId', 'createdAt'])
            .where('type', '=', type)
            .$if(pagination.cursor !== undefined, (eb) => eb.where('id', '<=', pagination.cursor))
            .orderBy('id', 'desc')
            .limit(pagination.limit + 1)
            .execute();
        return {
            items: items.slice(0, pagination.limit),
            nextCursor: items.at(pagination.limit)?.id,
        };
    }
    getAssetPathsByPaths(paths) {
        return this.db
            .selectFrom('asset')
            .leftJoin('asset_file', (join) => join.onRef('asset.id', '=', 'asset_file.assetId').on('asset_file.type', '=', enum_1.AssetFileType.EncodedVideo))
            .select(['asset.originalPath', 'asset_file.path as encodedVideoPath'])
            .where((eb) => eb.or([eb('originalPath', 'in', paths), eb('asset_file.path', 'in', paths)]))
            .execute();
    }
    getAssetFilePathsByPaths(paths) {
        return this.db.selectFrom('asset_file').select('path').where('path', 'in', paths).execute();
    }
    getPersonThumbnailPathsByPaths(paths) {
        return this.db
            .selectFrom('person')
            .select('person.thumbnailPath')
            .where('person.thumbnailPath', 'in', paths)
            .execute();
    }
    getAssetCount() {
        return this.db
            .selectFrom('asset')
            .select((eb) => eb.fn.countAll().as('count'))
            .executeTakeFirstOrThrow();
    }
    streamAllAssetPaths() {
        return this.db
            .selectFrom('asset')
            .leftJoin('asset_file', (join) => join.onRef('asset.id', '=', 'asset_file.assetId').on('asset_file.type', '=', enum_1.AssetFileType.EncodedVideo))
            .select(['originalPath', 'asset_file.path as encodedVideoPath'])
            .stream();
    }
    streamAllAssetFilePaths() {
        return this.db.selectFrom('asset_file').select(['path']).stream();
    }
    streamAssetPathsForMissingFiles() {
        return this.db
            .selectFrom((eb) => eb
            .selectFrom('asset')
            .where('asset.deletedAt', 'is', null)
            .select('asset.originalPath as path')
            .select((eb) => [
            eb.ref('asset.id').$castTo().as('assetId'),
            (0, kysely_1.sql) `null::uuid`.as('fileAssetId'),
        ])
            .unionAll(eb
            .selectFrom('asset_file')
            .select(['path'])
            .select((eb) => [
            (0, kysely_1.sql) `null::uuid`.as('assetId'),
            eb.ref('asset_file.id').$castTo().as('fileAssetId'),
        ]))
            .as('allPaths'))
            .leftJoin('integrity_report', (join) => join
            .on('integrity_report.type', '=', enum_1.IntegrityReport.MissingFile)
            .on((eb) => eb.or([
            eb('integrity_report.assetId', '=', eb.ref('allPaths.assetId')),
            eb('integrity_report.fileAssetId', '=', eb.ref('allPaths.fileAssetId')),
        ])))
            .select(['allPaths.path as path', 'allPaths.assetId', 'allPaths.fileAssetId', 'integrity_report.id as reportId'])
            .stream();
    }
    streamAssetChecksums(startMarker) {
        return this.db
            .selectFrom('asset')
            .where('asset.deletedAt', 'is', null)
            .leftJoin('integrity_report', (join) => join
            .onRef('integrity_report.assetId', '=', 'asset.id')
            .on('integrity_report.type', '=', enum_1.IntegrityReport.ChecksumFail))
            .select([
            'asset.originalPath',
            'asset.checksum',
            'asset.createdAt',
            'asset.id as assetId',
            'integrity_report.id as reportId',
        ])
            .where('asset.isExternal', '=', kysely_1.sql.lit(false))
            .$if(startMarker !== undefined, (qb) => qb.where('asset.createdAt', '>=', startMarker))
            .orderBy('asset.createdAt', 'asc')
            .stream();
    }
    streamIntegrityReports(type) {
        return this.db
            .selectFrom('integrity_report')
            .select(['id', 'type', 'path', 'assetId', 'fileAssetId'])
            .where('type', '=', type)
            .orderBy('createdAt', 'desc')
            .stream();
    }
    streamIntegrityReportsWithAssetChecksum(type) {
        return this.db
            .selectFrom('integrity_report')
            .select(['integrity_report.id as reportId', 'integrity_report.path'])
            .where('integrity_report.type', '=', type)
            .$if(type === enum_1.IntegrityReport.ChecksumFail, (eb) => eb.leftJoin('asset', 'integrity_report.path', 'asset.originalPath').select('asset.checksum'))
            .stream();
    }
    streamIntegrityReportsByProperty(property, filterType) {
        return this.db
            .selectFrom('integrity_report')
            .select(['id', 'path', 'assetId', 'fileAssetId'])
            .$if(filterType !== undefined, (eb) => eb.where('type', '=', filterType))
            .$if(property === undefined, (eb) => eb.where('assetId', 'is', null).where('fileAssetId', 'is', null))
            .$if(property !== undefined, (eb) => eb.where(property, 'is not', null))
            .stream();
    }
    deleteById(id) {
        return this.db.deleteFrom('integrity_report').where('id', '=', id).execute();
    }
    deleteByIds(ids) {
        return this.db.deleteFrom('integrity_report').where('id', 'in', ids).execute();
    }
};
exports.IntegrityRepository = IntegrityRepository;
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.STRING] }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "getById", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [] }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], IntegrityRepository.prototype, "getIntegrityReportSummary", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [{ cursor: decorators_1.DummyValue.NUMBER, limit: 100 }, decorators_1.DummyValue.STRING] }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String]),
    __metadata("design:returntype", Promise)
], IntegrityRepository.prototype, "getIntegrityReport", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.STRING] }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Array]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "getAssetPathsByPaths", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.STRING] }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Array]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "getAssetFilePathsByPaths", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.STRING] }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Array]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "getPersonThumbnailPathsByPaths", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [] }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "getAssetCount", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [], stream: true }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "streamAllAssetPaths", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [], stream: true }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "streamAllAssetFilePaths", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [], stream: true }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "streamAssetPathsForMissingFiles", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.DATE], stream: true }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Date]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "streamAssetChecksums", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.STRING], stream: true }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "streamIntegrityReports", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.STRING], stream: true }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "streamIntegrityReportsWithAssetChecksum", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.STRING], stream: true }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "streamIntegrityReportsByProperty", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.STRING] }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "deleteById", null);
__decorate([
    (0, decorators_1.GenerateSql)({ params: [decorators_1.DummyValue.STRING] }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Array]),
    __metadata("design:returntype", void 0)
], IntegrityRepository.prototype, "deleteByIds", null);
exports.IntegrityRepository = IntegrityRepository = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, nestjs_kysely_1.InjectKysely)()),
    __metadata("design:paramtypes", [kysely_1.Kysely])
], IntegrityRepository);
//# sourceMappingURL=integrity.repository.js.map