import { randomUUID } from 'node:crypto';
import { promises as fs, existsSync, mkdirSync } from 'node:fs';
import { dirname } from 'node:path';
import { summarizeError } from '../utils/error-display.js';
/**
 * JsonFileStore — generic JSON file persistence with atomic writes.
 *
 * Handles lazy loading, atomic writes via a temporary file, and ensures the
 * directory hierarchy exists. Invalid JSON and write failures are thrown so
 * callers do not mistake corrupted state for an empty store or persisted write.
 */
export class JsonFileStore {
    filePath;
    constructor(filePath) {
        this.filePath = filePath;
    }
    /** Load JSON data from disk, or return null if the file does not exist. */
    async load() {
        if (!existsSync(this.filePath)) {
            return null;
        }
        try {
            const raw = await fs.readFile(this.filePath, 'utf-8');
            return JSON.parse(raw);
        }
        catch (err) {
            throw new Error(`JsonFileStore failed to load ${this.filePath}: ${summarizeError(err)}`);
        }
    }
    /** Atomically persist data to disk. */
    async save(data) {
        mkdirSync(dirname(this.filePath), { recursive: true });
        const tmpPath = `${this.filePath}.tmp.${process.pid}.${randomUUID()}`;
        const content = JSON.stringify(data, null, 2) + '\n';
        try {
            await fs.writeFile(tmpPath, content, 'utf-8');
            await fs.rename(tmpPath, this.filePath);
        }
        catch (error) {
            await fs.rm(tmpPath, { force: true }).catch(() => undefined);
            throw error;
        }
    }
}
