"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "SnapshotTableCleaner", {
    enumerable: true,
    get: function() {
        return SnapshotTableCleaner;
    }
});
const _config = /*#__PURE__*/ _interop_require_default(require("config"));
const _datefns = require("date-fns");
const _sequelize = require("sequelize");
const _tasks = require("@tamanu/shared/tasks");
const _logging = require("@tamanu/shared/services/logging");
const _sleepAsync = require("@tamanu/utils/sleepAsync");
const _sync = require("@tamanu/database/sync");
const _ = require(".");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
let SnapshotTableCleaner = class SnapshotTableCleaner extends _tasks.ScheduledTask {
    getName() {
        return 'SnapshotTableCleaner';
    }
    getWhere() {
        return {
            completedAt: {
                [_sequelize.Op.lt]: (0, _datefns.subHours)(new Date(), this.config.retentionHours)
            },
            errors: {
                [_sequelize.Op.not]: null
            },
            snapshotDroppedAt: {
                [_sequelize.Op.is]: null
            }
        };
    }
    async countQueue() {
        const { SyncSession } = this.store.models;
        return SyncSession.count({
            where: this.getWhere()
        });
    }
    async run() {
        const { SyncSession } = this.store.models;
        const { batchSize, batchSleepAsyncDurationInMilliseconds } = this.config;
        if (!batchSize || !batchSleepAsyncDurationInMilliseconds) {
            throw new _.InvalidConfigError('batchSize and batchSleepAsyncDurationInMilliseconds must be set for SnapshotTableCleaner');
        }
        const sessions = await SyncSession.findAll({
            where: this.getWhere(),
            attributes: [
                'id'
            ],
            order: [
                [
                    'completedAt',
                    'ASC'
                ]
            ],
            limit: batchSize,
            raw: true
        });
        if (sessions.length === 0) return;
        _logging.log.info('SnapshotTableCleaner.startBatch', {
            batchSize: sessions.length
        });
        const droppedIds = [];
        for(let i = 0; i < sessions.length; i++){
            const { id } = sessions[i];
            try {
                await (0, _sync.dropSnapshotTable)(this.store.sequelize, id);
                await (0, _sync.dropMarkedForSyncPatientsTable)(this.store.sequelize, id);
                droppedIds.push(id);
            } catch (error) {
                _logging.log.warn('SnapshotTableCleaner.dropFailed', {
                    sessionId: id,
                    error: error instanceof Error ? error.message : String(error)
                });
            }
            if (i < sessions.length - 1) {
                await (0, _sleepAsync.sleepAsync)(batchSleepAsyncDurationInMilliseconds);
            }
        }
        if (droppedIds.length > 0) {
            await SyncSession.update({
                snapshotDroppedAt: new Date()
            }, {
                where: {
                    id: {
                        [_sequelize.Op.in]: droppedIds
                    }
                }
            });
        }
    }
    constructor(context, overrideConfig = null){
        const conf = {
            ..._config.default.schedules.snapshotTableCleaner,
            ...overrideConfig
        };
        const { schedule, jitterTime, enabled } = conf;
        super(schedule, _logging.log, jitterTime, enabled);
        this.config = conf;
        this.store = context.store;
    }
};

//# sourceMappingURL=SnapshotTableCleaner.js.map