import { writeFile } from 'fs/promises';
import { join } from 'path';
import * as lockfile from 'proper-lockfile';
import { ensureDir, fileExists } from './utils.js';
import { createLogger } from './logger.js';
import { ClientError } from './errors.js';
const logger = createLogger('file-lock');
const LOCK_TIMEOUT = 5000;
export async function withFileLock(filePath, operation, defaultContent = '{}') {
    const dir = join(filePath, '..');
    await ensureDir(dir);
    if (!(await fileExists(filePath))) {
        await writeFile(filePath, defaultContent, { encoding: 'utf-8', mode: 0o600 });
    }
    let release;
    try {
        logger.debug(`Acquiring file lock for ${filePath}`);
        release = await lockfile.lock(filePath, {
            retries: {
                retries: 5,
                minTimeout: 100,
                maxTimeout: LOCK_TIMEOUT,
            },
        });
        logger.debug('Lock acquired');
        return await operation();
    }
    catch (error) {
        if (error.message.includes('ELOCKED')) {
            throw new ClientError(`File is locked by another process: ${filePath}. Please try again.`);
        }
        throw error;
    }
    finally {
        if (release) {
            try {
                await release();
                logger.debug('Lock released');
            }
            catch (error) {
                logger.warn('Failed to release lock:', error);
            }
        }
    }
}
//# sourceMappingURL=file-lock.js.map