/**
 * Cross-Platform Buffer Handling Module
 *
 * Ensures consistent data representation across ARM and x86 architectures
 * by using explicit buffer operations that are not affected by processor endianness.
 */
export class CrossPlatformBuffer {
    systemEndianness;
    constructor() {
        // Detect system endianness for debugging/logging purposes
        this.systemEndianness = this.detectSystemEndianness();
    }
    /**
     * Detect system endianness (for logging/debugging only)
     */
    detectSystemEndianness() {
        const arrayBuffer = new ArrayBuffer(2);
        const uint8Array = new Uint8Array(arrayBuffer);
        const uint16Array = new Uint16Array(arrayBuffer);
        uint16Array[0] = 0x1234;
        if (uint8Array[0] === 0x12) {
            return "BE"; // Big Endian
        }
        else {
            return "LE"; // Little Endian
        }
    }
    /**
     * Get system endianness
     */
    getSystemEndianness() {
        return this.systemEndianness;
    }
    /**
     * Convert float32 to two 16-bit registers with explicit endianness control
     */
    float32ToRegisters(value, endian = "LE", wordSwap = false, byteSwap = false) {
        // Create a buffer to hold the float32
        const buffer = new ArrayBuffer(4);
        const float32View = new Float32Array(buffer);
        const dataView = new DataView(buffer);
        // Write the float32 value
        float32View[0] = value;
        // Read as two 16-bit values with specified endianness
        let reg1, reg2;
        if (endian === "BE") {
            // Big Endian: most significant word first
            reg1 = dataView.getUint16(0, false); // Big endian read
            reg2 = dataView.getUint16(2, false);
        }
        else {
            // Little Endian: least significant word first
            reg1 = dataView.getUint16(0, true); // Little endian read
            reg2 = dataView.getUint16(2, true);
        }
        // Apply word swap if needed
        if (wordSwap) {
            [reg1, reg2] = [reg2, reg1];
        }
        // Apply byte swap within each word if needed
        if (byteSwap) {
            reg1 = ((reg1 & 0xff) << 8) | ((reg1 >> 8) & 0xff);
            reg2 = ((reg2 & 0xff) << 8) | ((reg2 >> 8) & 0xff);
        }
        return [reg1, reg2];
    }
    /**
     * Convert two 16-bit registers to float32 with explicit endianness control
     */
    registersToFloat32(reg1, reg2, endian = "LE", wordSwap = false, byteSwap = false) {
        // Apply byte swap within each word if needed
        if (byteSwap) {
            reg1 = ((reg1 & 0xff) << 8) | ((reg1 >> 8) & 0xff);
            reg2 = ((reg2 & 0xff) << 8) | ((reg2 >> 8) & 0xff);
        }
        // Apply word swap if needed
        if (wordSwap) {
            [reg1, reg2] = [reg2, reg1];
        }
        // Create a buffer and write the registers
        const buffer = new ArrayBuffer(4);
        const dataView = new DataView(buffer);
        if (endian === "BE") {
            // Big Endian: write as big endian
            dataView.setUint16(0, reg1, false);
            dataView.setUint16(2, reg2, false);
        }
        else {
            // Little Endian: write as little endian
            dataView.setUint16(0, reg1, true);
            dataView.setUint16(2, reg2, true);
        }
        // Read as float32
        const float32View = new Float32Array(buffer);
        return float32View[0];
    }
    /**
     * Convert int32 to two 16-bit registers
     */
    int32ToRegisters(value, endian = "LE", wordSwap = false) {
        const buffer = new ArrayBuffer(4);
        const dataView = new DataView(buffer);
        // Write the int32 value
        dataView.setInt32(0, value, endian === "LE");
        // Read as two 16-bit values
        let reg1 = dataView.getUint16(0, endian === "LE");
        let reg2 = dataView.getUint16(2, endian === "LE");
        if (wordSwap) {
            [reg1, reg2] = [reg2, reg1];
        }
        return [reg1, reg2];
    }
    /**
     * Convert two 16-bit registers to int32
     */
    registersToInt32(reg1, reg2, endian = "LE", wordSwap = false) {
        if (wordSwap) {
            [reg1, reg2] = [reg2, reg1];
        }
        const buffer = new ArrayBuffer(4);
        const dataView = new DataView(buffer);
        dataView.setUint16(0, reg1, endian === "LE");
        dataView.setUint16(2, reg2, endian === "LE");
        return dataView.getInt32(0, endian === "LE");
    }
    /**
     * Convert uint32 to two 16-bit registers
     */
    uint32ToRegisters(value, endian = "LE", wordSwap = false) {
        const buffer = new ArrayBuffer(4);
        const dataView = new DataView(buffer);
        // Write the uint32 value
        dataView.setUint32(0, value, endian === "LE");
        // Read as two 16-bit values
        let reg1 = dataView.getUint16(0, endian === "LE");
        let reg2 = dataView.getUint16(2, endian === "LE");
        if (wordSwap) {
            [reg1, reg2] = [reg2, reg1];
        }
        return [reg1, reg2];
    }
    /**
     * Convert two 16-bit registers to uint32
     */
    registersToUint32(reg1, reg2, endian = "LE", wordSwap = false) {
        if (wordSwap) {
            [reg1, reg2] = [reg2, reg1];
        }
        const buffer = new ArrayBuffer(4);
        const dataView = new DataView(buffer);
        dataView.setUint16(0, reg1, endian === "LE");
        dataView.setUint16(2, reg2, endian === "LE");
        return dataView.getUint32(0, endian === "LE");
    }
    /**
     * Convert boolean to register value
     */
    boolToRegister(value) {
        return value ? 1 : 0;
    }
    /**
     * Convert register value to boolean
     */
    registerToBool(value) {
        return value !== 0;
    }
    /**
     * Convert int16 to register with proper sign extension
     */
    int16ToRegister(value) {
        // Ensure value is within int16 range
        value = Math.max(-32768, Math.min(32767, value));
        // Convert to unsigned representation
        if (value < 0) {
            return 0x10000 + value; // Two's complement
        }
        return value;
    }
    /**
     * Convert register to int16 with proper sign handling
     */
    registerToInt16(value) {
        // Check if the sign bit is set
        if (value & 0x8000) {
            // Negative number in two's complement
            return value - 0x10000;
        }
        return value;
    }
    /**
     * Convert string to register array
     */
    stringToRegisters(str, maxLength = 32) {
        const registers = [];
        const buffer = Buffer.from(str, "utf8");
        // Pad with zeros to ensure even number of bytes
        const paddedLength = Math.min(maxLength, Math.ceil(buffer.length / 2) * 2);
        for (let i = 0; i < paddedLength; i += 2) {
            const byte1 = buffer[i] || 0;
            const byte2 = buffer[i + 1] || 0;
            registers.push((byte1 << 8) | byte2);
        }
        return registers;
    }
    /**
     * Convert register array to string
     */
    registersToString(registers) {
        const bytes = [];
        for (const reg of registers) {
            bytes.push((reg >> 8) & 0xff); // High byte
            bytes.push(reg & 0xff); // Low byte
        }
        // Remove trailing zeros
        while (bytes.length > 0 && bytes[bytes.length - 1] === 0) {
            bytes.pop();
        }
        return Buffer.from(bytes).toString("utf8");
    }
    /**
     * Validate register value is within 16-bit range
     */
    validateRegisterValue(value) {
        return Number.isInteger(value) && value >= 0 && value <= 0xffff;
    }
    /**
     * Create a buffer configuration for consistent handling
     */
    createBufferConfig(options = {}) {
        return {
            endian: options.endian || "LE",
            wordSwap: options.wordSwap || false,
            byteSwap: options.byteSwap || false,
        };
    }
}
// Singleton instance
let crossPlatformBuffer = null;
export function getCrossPlatformBuffer() {
    if (!crossPlatformBuffer) {
        crossPlatformBuffer = new CrossPlatformBuffer();
    }
    return crossPlatformBuffer;
}
export default CrossPlatformBuffer;
//# sourceMappingURL=crossPlatformBuffer.js.map