"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DlcTransactionsV0 = exports.CloseType = exports.DlcTransactions = void 0;
const bitcoin_1 = require("@node-dlc/bitcoin");
const bufio_1 = require("@node-dlc/bufio");
const MessageType_1 = require("../MessageType");
/**
 * DlcTransactions message contains information about state of DLC
 * contract such as fundtx and closetx
 */
class DlcTransactions {
    constructor() {
        /**
         * The type for dlc_transactions message. dlc_transactions = 61230
         */
        this.type = DlcTransactions.type;
        this.fundEpoch = {
            hash: Buffer.alloc(32),
            height: 0,
        };
        this.fundBroadcastHeight = 0;
        this.cets = [];
        this.closeEpoch = {
            hash: Buffer.alloc(32),
            height: 0,
        };
        this.closeTxHash = Buffer.alloc(32);
        this.closeType = 0;
        this.closeBroadcastHeight = 0;
    }
    /**
     * Deserializes a dlc_transactions message
     * @param buf
     */
    static deserialize(buf, parseCets = true) {
        const instance = new DlcTransactions();
        const reader = new bufio_1.BufferReader(buf);
        reader.readUInt16BE(); // read type
        instance.contractId = reader.readBytes(32);
        const fundTxLen = reader.readUInt16BE();
        instance.fundTx = bitcoin_1.Tx.decode(bufio_1.StreamReader.fromBuffer(reader.readBytes(fundTxLen)));
        instance.fundTxVout = reader.readUInt32BE();
        const fundHash = reader.readBytes(32);
        const fundHeight = reader.readUInt32BE();
        instance.fundEpoch = {
            hash: fundHash,
            height: fundHeight,
        };
        instance.fundBroadcastHeight = reader.readUInt32BE();
        const refundTxLen = reader.readUInt16BE();
        instance.refundTx = bitcoin_1.Tx.decode(bufio_1.StreamReader.fromBuffer(reader.readBytes(refundTxLen)));
        const numCets = reader.readBigSize(); // num_cets
        for (let i = 0; i < numCets; i++) {
            const cetLen = reader.readUInt16BE();
            if (parseCets || i === 0) {
                instance.cets.push(bitcoin_1.Tx.decode(bufio_1.StreamReader.fromBuffer(reader.readBytes(cetLen))));
            }
            else {
                reader.readBytes(cetLen);
            }
        }
        const closeHash = reader.readBytes(32);
        const closeHeight = reader.readUInt32BE();
        instance.closeEpoch = {
            hash: closeHash,
            height: closeHeight,
        };
        instance.closeTxHash = reader.readBytes(32);
        instance.closeType = reader.readUInt8();
        instance.closeBroadcastHeight = reader.readUInt32BE();
        return instance;
    }
    /**
     * Converts dlc_transactions to JSON
     */
    toJSON() {
        return {
            type: this.type,
            contractId: this.contractId.toString('hex'),
            fundTx: this.fundTx.serialize().toString('hex'),
            fundTxVout: this.fundTxVout,
            fundEpoch: {
                hash: this.fundEpoch.hash.toString('hex'),
                height: this.fundEpoch.height,
            },
            fundBroadcastHeight: this.fundBroadcastHeight,
            refundTx: this.refundTx.serialize().toString('hex'),
            cets: this.cets.map((cet) => cet.serialize().toString('hex')),
            closeEpoch: {
                hash: this.closeEpoch.hash.toString('hex'),
                height: this.closeEpoch.height,
            },
            closeTxHash: this.closeTxHash.toString('hex'),
            closeType: closeTypeToStr(this.closeType),
            closeBroadcastHeight: this.closeBroadcastHeight,
        };
    }
    /**
     * Serializes the dlc_transactions message into a Buffer
     */
    serialize() {
        const writer = new bufio_1.BufferWriter();
        writer.writeUInt16BE(this.type);
        writer.writeBytes(this.contractId);
        writer.writeUInt16BE(this.fundTx.serialize().length);
        writer.writeBytes(this.fundTx.serialize());
        writer.writeUInt32BE(this.fundTxVout);
        writer.writeBytes(this.fundEpoch.hash);
        writer.writeUInt32BE(this.fundEpoch.height);
        writer.writeUInt32BE(this.fundBroadcastHeight);
        writer.writeUInt16BE(this.refundTx.serialize().length);
        writer.writeBytes(this.refundTx.serialize());
        writer.writeBigSize(this.cets.length);
        for (const cet of this.cets) {
            writer.writeUInt16BE(cet.serialize().length);
            writer.writeBytes(cet.serialize());
        }
        writer.writeBytes(this.closeEpoch.hash);
        writer.writeUInt32BE(this.closeEpoch.height);
        writer.writeBytes(this.closeTxHash);
        writer.writeUInt8(this.closeType);
        writer.writeUInt32BE(this.closeBroadcastHeight);
        return writer.toBuffer();
    }
}
exports.DlcTransactions = DlcTransactions;
DlcTransactions.type = MessageType_1.MessageType.DlcTransactions;
const closeTypeToStr = (closeType) => {
    switch (closeType) {
        case CloseType.ExecuteClose:
            return 'ExecuteClose';
        case CloseType.RefundClose:
            return 'RefundClose';
        case CloseType.CooperativeClose:
            return 'CooperativeClose';
        default:
            return 'NotClosed';
    }
};
var CloseType;
(function (CloseType) {
    CloseType[CloseType["NotClosed"] = 0] = "NotClosed";
    CloseType[CloseType["ExecuteClose"] = 1] = "ExecuteClose";
    CloseType[CloseType["RefundClose"] = 2] = "RefundClose";
    CloseType[CloseType["CooperativeClose"] = 3] = "CooperativeClose";
})(CloseType = exports.CloseType || (exports.CloseType = {}));
// Backward compatibility aliases
exports.DlcTransactionsV0 = DlcTransactions;
//# sourceMappingURL=DlcTransactions.js.map