"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.atomicWriteJSON = atomicWriteJSON;
exports.readJSON = readJSON;
exports.deleteFile = deleteFile;
exports.ensureDir = ensureDir;
exports.fileExists = fileExists;
exports.listFiles = listFiles;
exports.listDirectories = listDirectories;
const promises_1 = require("fs/promises");
const fs_1 = require("fs");
const path_1 = require("path");
const crypto_1 = require("crypto");
const logger_js_1 = require("../../utils/logger.js");
const log = (0, logger_js_1.createModuleLogger)('file-ops');
/**
 * Atomically writes JSON data to a file.
 * Writes to a temp file first, then renames to prevent corruption on crash.
 */
async function atomicWriteJSON(filePath, data) {
    const dir = (0, path_1.dirname)(filePath);
    await ensureDir(dir);
    const tempPath = `${filePath}.${(0, crypto_1.randomBytes)(6).toString('hex')}.tmp`;
    const content = JSON.stringify(data, null, 2);
    await (0, promises_1.writeFile)(tempPath, content, 'utf-8');
    await (0, promises_1.rename)(tempPath, filePath);
    log.debug({ filePath }, 'Atomic write completed');
}
/**
 * Safely reads and parses a JSON file.
 * Returns null if the file doesn't exist or contains invalid JSON.
 */
async function readJSON(filePath) {
    try {
        if (!(0, fs_1.existsSync)(filePath))
            return null;
        const content = await (0, promises_1.readFile)(filePath, 'utf-8');
        return JSON.parse(content);
    }
    catch (err) {
        log.error({ filePath, err }, 'Failed to read JSON file');
        return null;
    }
}
/**
 * Deletes a file. Returns true if deleted, false if not found or on error.
 */
async function deleteFile(filePath) {
    try {
        if (!(0, fs_1.existsSync)(filePath))
            return false;
        await (0, promises_1.unlink)(filePath);
        return true;
    }
    catch (err) {
        log.error({ filePath, err }, 'Failed to delete file');
        return false;
    }
}
/**
 * Ensures a directory exists, creating it recursively if needed.
 */
async function ensureDir(dirPath) {
    await (0, promises_1.mkdir)(dirPath, { recursive: true });
}
/**
 * Synchronously checks if a file exists.
 */
function fileExists(filePath) {
    return (0, fs_1.existsSync)(filePath);
}
/**
 * Lists files in a directory, optionally filtering by extension.
 * Returns an empty array if the directory doesn't exist.
 */
async function listFiles(dirPath, extension) {
    try {
        if (!(0, fs_1.existsSync)(dirPath))
            return [];
        const entries = await (0, promises_1.readdir)(dirPath);
        if (extension) {
            return entries.filter(e => e.endsWith(extension));
        }
        return entries;
    }
    catch (err) {
        log.error({ dirPath, err }, 'Failed to list files');
        return [];
    }
}
/**
 * Lists subdirectories in a directory.
 * Returns an empty array if the directory doesn't exist.
 */
async function listDirectories(dirPath) {
    try {
        if (!(0, fs_1.existsSync)(dirPath))
            return [];
        const entries = await (0, promises_1.readdir)(dirPath, { withFileTypes: true });
        return entries.filter(e => e.isDirectory()).map(e => e.name);
    }
    catch (err) {
        log.error({ dirPath, err }, 'Failed to list directories');
        return [];
    }
}
//# sourceMappingURL=file-ops.js.map