"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IrcMessageWithoutSig = exports.IrcMessageV0 = exports.IrcMessage = void 0;
const bufio_1 = require("@node-dlc/bufio");
const checksum_1 = require("@node-dlc/checksum");
const MessageType_1 = require("../MessageType");
const MAX_DATA_LEN = 190;
class IrcMessage {
    static deserialize(buf) {
        const reader = new bufio_1.BufferReader(buf);
        const type = Number(reader.readUInt16BE());
        switch (type) {
            case MessageType_1.MessageType.IrcMessageV0:
                return IrcMessageV0.deserialize(buf);
            default:
                throw new Error(`Irc message type must be IrcMessageV0`);
        }
    }
}
exports.IrcMessage = IrcMessage;
/**
 * IrcMessage contains information for Irc message packet.
 */
class IrcMessageV0 extends IrcMessage {
    constructor() {
        super(...arguments);
        this.type = IrcMessageV0.type;
    }
    static fromBuffer(buf, pubkey) {
        const instances = [];
        const checksum = (0, checksum_1.crc32c)(buf);
        const sequenceLength = Math.ceil(buf.length / MAX_DATA_LEN);
        const reader = new bufio_1.BufferReader(buf);
        const bufLen = buf.length;
        const currentTime = Math.floor(new Date().getTime() / 1000);
        for (let i = 0; i < sequenceLength; i++) {
            const sequenceNumber = i;
            const instance = new IrcMessageV0();
            instance.sequenceLength = BigInt(sequenceLength);
            instance.sequenceNumber = BigInt(sequenceNumber);
            instance.checksum = checksum;
            instance.pubkey = pubkey;
            instance.timestamp = currentTime;
            instance.data = reader.readBytes(Math.min(MAX_DATA_LEN, bufLen - reader.position));
            instances.push(instance);
        }
        return instances;
    }
    static fromString(str, pubkey) {
        const buf = Buffer.from(str);
        return IrcMessageV0.fromBuffer(buf, pubkey);
    }
    /**
     * Deserializes an irc message
     * @param buf
     */
    static deserialize(buf) {
        const instance = new IrcMessageV0();
        const reader = new bufio_1.BufferReader(buf);
        reader.readBigSize(); // read type
        instance.length = reader.readBigSize();
        instance.sequenceLength = reader.readBigSize();
        instance.sequenceNumber = reader.readBigSize();
        instance.checksum = reader.readUInt32BE();
        instance.signature = reader.readBytes(64);
        instance.pubkey = reader.readBytes(33);
        instance.timestamp = reader.readUInt32BE();
        const dataLen = reader.readUInt16BE();
        instance.data = reader.readBytes(dataLen);
        return instance;
    }
    serializeWithoutSig() {
        const writer = new bufio_1.BufferWriter();
        writer.writeBigSize(this.sequenceLength);
        writer.writeBigSize(this.sequenceNumber);
        writer.writeUInt64BE(this.checksum);
        writer.writeBytes(this.pubkey);
        writer.writeUInt32BE(this.timestamp);
        writer.writeUInt16BE(this.data.length);
        writer.writeBytes(this.data);
        return writer.toBuffer();
    }
    /**
     * Serializes the irc_message_v0
     */
    serialize() {
        const writer = new bufio_1.BufferWriter();
        writer.writeBigSize(this.type);
        const dataWriter = new bufio_1.BufferWriter();
        dataWriter.writeBigSize(this.sequenceLength);
        dataWriter.writeBigSize(this.sequenceNumber);
        dataWriter.writeUInt32BE(this.checksum);
        dataWriter.writeBytes(this.signature);
        dataWriter.writeBytes(this.pubkey);
        dataWriter.writeUInt32BE(this.timestamp);
        dataWriter.writeUInt16BE(this.data.length);
        dataWriter.writeBytes(this.data);
        writer.writeBigSize(dataWriter.size);
        writer.writeBytes(dataWriter.toBuffer());
        return writer.toBuffer();
    }
}
exports.IrcMessageV0 = IrcMessageV0;
IrcMessageV0.type = MessageType_1.MessageType.IrcMessageV0;
class IrcMessageWithoutSig {
    constructor(sequenceLength, sequenceNumber, checksum, signature, pubkey, data) {
        this.sequenceLength = sequenceLength;
        this.sequenceNumber = sequenceNumber;
        this.checksum = checksum;
        this.signature = signature;
        this.pubkey = pubkey;
        this.data = data;
    }
}
exports.IrcMessageWithoutSig = IrcMessageWithoutSig;
//# sourceMappingURL=IrcMessage.js.map