import { KeetaAnchorQueueStorageDriverMemory } from '../index.js';
import { MethodLogger } from '../internal.js';
import * as fs from 'fs';
export default class KeetaAnchorQueueStorageDriverFile extends KeetaAnchorQueueStorageDriverMemory {
    filePath;
    syncInProgress = null;
    name = 'KeetaAnchorQueueStorageDriverFile';
    constructor(options) {
        super(options);
        this.filePath = options.filePath;
        this.loadFile();
    }
    clone(options) {
        const cloned = new KeetaAnchorQueueStorageDriverFile({
            logger: this.logger,
            id: `${this.id}::${this.partitionCounter++}`,
            path: [...this.path],
            filePath: this.filePath,
            ...options
        });
        cloned.queueStorage = this.queueStorage;
        return (cloned);
    }
    methodLogger(method) {
        return (MethodLogger(this.logger, {
            class: 'KeetaAnchorQueueStorageDriverFile',
            file: 'src/lib/queue/drivers/queue_file.ts',
            method: method,
            instanceID: this.id
        }));
    }
    loadFile() {
        if (!fs.existsSync(this.filePath)) {
            return;
        }
        const input = fs.readFileSync(this.filePath, 'utf-8');
        const parsed = JSON.parse(input, function (key, inputValue) {
            let nominalValue = this[key];
            if (key === 'created' || key === 'updated') {
                if (typeof nominalValue === 'string' || typeof nominalValue === 'number') {
                    nominalValue = new Date(nominalValue);
                }
            }
            if (key === 'idempotentKeys' && Array.isArray(inputValue)) {
                nominalValue = new Set(inputValue);
            }
            return (nominalValue);
        });
        if (typeof parsed !== 'object' || parsed === null || !('queue' in parsed)) {
            throw (new Error('Invalid queue file format'));
        }
        // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
        const data = parsed;
        Object.assign(this.queueStorage, data.queue);
    }
    async syncFile() {
        await this.syncInProgress;
        this.syncInProgress = (async () => {
            const tmpFilePath = `${this.filePath}.${crypto.randomUUID()}`;
            try {
                fs.writeFileSync(tmpFilePath, JSON.stringify({
                    queue: this.queueStorage
                }, function (key, inputValue) {
                    if (key === 'created' || key === 'updated') {
                        if (inputValue instanceof Date) {
                            return (inputValue.toISOString());
                        }
                    }
                    if (key === 'idempotentKeys') {
                        if (inputValue instanceof Set) {
                            return (Array.from(inputValue));
                        }
                    }
                    return (inputValue);
                }, 2), 'utf-8');
                fs.renameSync(tmpFilePath, this.filePath);
            }
            finally {
                try {
                    fs.unlinkSync(tmpFilePath);
                }
                catch {
                    /* Ignore */
                }
            }
        })();
        await this.syncInProgress;
    }
    async add(...args) {
        const retval = await super.add(...args);
        await this.syncFile();
        return (retval);
    }
    async setStatus(...args) {
        const retval = await super.setStatus(...args);
        await this.syncFile();
        return (retval);
    }
}
//# sourceMappingURL=queue_file.js.map