import { assert } from "../assert.js";

/**
 * 2147483647
 * @type {number}
 */
const MAX_VALUE = 2 ** 31 - 1;

/**
 * -2147483648
 * @type {number}
 */
const MIN_VALUE = -1 * (2 ** 31);

/**
 * Converts an integer to easily readable binary string representation
 * @example 1024    -> "00000000 00000000 00000100 00000000"
 * @example -1      -> "11111111 11111111 11111111 11111111"
 * @param {number} input_value
 * @param {string} [byte_separator] insert this string between each group of 8 bits, defaults to a space
 * @param {number} [bit_count] how many bits to actually render, cropped on the LSB
 * @returns {string}
 */
export function int32_to_binary_string(input_value, byte_separator = " ", bit_count = 32) {
    // @see https://stackoverflow.com/questions/9939760/how-do-i-convert-an-integer-to-binary-in-javascript
    assert.lessThanOrEqual(bit_count, 32);

    // nMask must be between -2147483648 and 2147483647
    if (input_value > MAX_VALUE) {
        throw "number too large. number shouldn't be > 2**31-1";//added
    }
    if (input_value < MIN_VALUE) {
        throw "number too far negative, number shouldn't be < 2**31"//added
    }

    assert.isInteger(input_value, 'input_value');

    let result = '';

    for (let bit_index = 0; bit_index < bit_count; bit_index++) {

        if (bit_index > 0 && bit_index % 8 === 0) {
            result += byte_separator;
        }

        const bit_value = (input_value << (bit_index + 32 - bit_count)) >>> 31;

        result += String(bit_value);

    }

    return result;
}
