import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core";
import fs from "node:fs/promises";
import { NVMAccess } from "../common/definitions.js";
/** An implementation of NVMIO for the filesystem */
export class NVMFileIO {
    constructor(path) {
        this._path = path;
        this._accessMode = NVMAccess.None;
    }
    _path;
    _handle;
    _chunkSize = 16 * 1024; // We could read more, but 16 KB chunks are more than enough for reading NVM contents
    async open(access) {
        let flags;
        switch (access) {
            case NVMAccess.Read:
                flags = "r";
                break;
            case NVMAccess.Write:
            case NVMAccess.ReadWrite:
                // Read/Write, don't create, don't truncate
                flags = "r+";
                access = NVMAccess.ReadWrite;
                break;
            default:
                throw new Error("Invalid access mode");
        }
        this._handle = await fs.open(this._path, flags);
        this._size = (await this._handle.stat()).size;
        this._accessMode = access;
        return access;
    }
    _size;
    get size() {
        if (this._size == undefined) {
            throw new ZWaveError("The NVM file is not open", ZWaveErrorCodes.NVM_NotOpen);
        }
        return this._size;
    }
    _accessMode;
    get accessMode() {
        return this._accessMode;
    }
    determineChunkSize() {
        return Promise.resolve(this._chunkSize);
    }
    async read(offset, length) {
        if (this._handle == undefined) {
            throw new ZWaveError("The NVM file is not open", ZWaveErrorCodes.NVM_NotOpen);
        }
        const readResult = await this._handle.read({
            buffer: new Uint8Array(length),
            position: offset,
        });
        const endOfFile = offset + readResult.bytesRead >= this.size;
        return {
            buffer: readResult.buffer.subarray(0, readResult.bytesRead),
            endOfFile,
        };
    }
    async write(offset, data) {
        if (this._handle == undefined) {
            throw new ZWaveError("The NVM file is not open", ZWaveErrorCodes.NVM_NotOpen);
        }
        if (offset + data.length > this.size) {
            throw new ZWaveError("Write would exceed the NVM size", ZWaveErrorCodes.NVM_NoSpace);
        }
        const writeResult = await this._handle.write(data, 0, data.length, offset);
        const endOfFile = offset + writeResult.bytesWritten >= this.size;
        return { bytesWritten: writeResult.bytesWritten, endOfFile };
    }
    async close() {
        await this._handle?.close();
        this._handle = undefined;
        this._accessMode = NVMAccess.None;
        this._size = undefined;
    }
}
//# sourceMappingURL=NVMFileIO.js.map