import * as asn1js from "asn1js";
import { isBufferSource, toArrayBuffer, } from "@peculiar/utils/bytes";
export class BitString {
    unusedBits = 0;
    value = new ArrayBuffer(0);
    constructor(params, unusedBits = 0) {
        if (params) {
            if (typeof params === "number") {
                this.fromNumber(params);
            }
            else if (isBufferSource(params)) {
                this.unusedBits = unusedBits;
                this.value = toArrayBuffer(params);
            }
            else {
                throw TypeError("Unsupported type of 'params' argument for BitString");
            }
        }
    }
    fromASN(asn) {
        if (!(asn instanceof asn1js.BitString)) {
            throw new TypeError("Argument 'asn' is not instance of ASN.1 BitString");
        }
        this.unusedBits = asn.valueBlock.unusedBits;
        this.value = toArrayBuffer(asn.valueBlock.valueHex);
        return this;
    }
    toASN() {
        return new asn1js.BitString({
            unusedBits: this.unusedBits, valueHex: this.value,
        });
    }
    toSchema(name) {
        return new asn1js.BitString({ name });
    }
    toNumber() {
        let res = "";
        const uintArray = new Uint8Array(this.value);
        for (const octet of uintArray) {
            res += octet.toString(2).padStart(8, "0");
        }
        res = res.split("").reverse().join("");
        if (this.unusedBits) {
            res = res.slice(this.unusedBits).padStart(this.unusedBits, "0");
        }
        return parseInt(res, 2);
    }
    fromNumber(value) {
        let bits = value.toString(2);
        const octetSize = (bits.length + 7) >> 3;
        this.unusedBits = (octetSize << 3) - bits.length;
        const octets = new Uint8Array(octetSize);
        bits = bits
            .padStart(octetSize << 3, "0")
            .split("")
            .reverse()
            .join("");
        let index = 0;
        while (index < octetSize) {
            octets[index] = parseInt(bits.slice(index << 3, (index << 3) + 8), 2);
            index++;
        }
        this.value = octets.buffer;
    }
}
