"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AtomicFileDataAccessor = void 0;
const node_crypto_1 = require("node:crypto");
const fs_extra_1 = require("fs-extra");
const PathUtil_1 = require("../../util/PathUtil");
const FileDataAccessor_1 = require("./FileDataAccessor");
/**
 * AtomicDataAccessor that uses the file system to store documents as files and containers as folders.
 * Data will first be written to a temporary location and only if no errors occur
 * will the data be written to the desired location.
 */
class AtomicFileDataAccessor extends FileDataAccessor_1.FileDataAccessor {
    tempFilePath;
    constructor(resourceMapper, rootFilePath, tempFilePath) {
        super(resourceMapper);
        this.tempFilePath = (0, PathUtil_1.joinFilePath)(rootFilePath, tempFilePath);
        (0, fs_extra_1.ensureDirSync)(this.tempFilePath);
    }
    /**
     * Writes the given data as a file (and potential metadata as additional file).
     * Data will first be written to a temporary file and if no errors occur only then the
     * file will be moved to desired destination.
     * If the stream errors it is made sure the temporary file will be deleted.
     * The metadata file will only be written if the data was written successfully.
     */
    async writeDocument(identifier, data, metadata) {
        const link = await this.resourceMapper.mapUrlToFilePath(identifier, false, metadata.contentType);
        // Generate temporary file name
        const tempFilePath = (0, PathUtil_1.joinFilePath)(this.tempFilePath, `temp-${(0, node_crypto_1.randomUUID)()}.txt`);
        try {
            await this.writeDataFile(tempFilePath, data);
            // Check if we already have a corresponding file with a different extension
            await this.verifyExistingExtension(link);
            // When no quota errors occur move the file to its desired location
            await (0, fs_extra_1.rename)(tempFilePath, link.filePath);
        }
        catch (error) {
            // Delete the data already written
            try {
                if ((await this.getStats(tempFilePath)).isFile()) {
                    await (0, fs_extra_1.unlink)(tempFilePath);
                }
            }
            catch {
                throw error;
            }
            throw error;
        }
        await this.writeMetadataFile(link, metadata);
    }
}
exports.AtomicFileDataAccessor = AtomicFileDataAccessor;
//# sourceMappingURL=AtomicFileDataAccessor.js.map