"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WormholeInstruction = exports.WormholeInstructionCoder = void 0;
var utils_1 = require("../../utils");
var WormholeInstructionCoder = /** @class */ (function () {
    function WormholeInstructionCoder(_) {
    }
    WormholeInstructionCoder.prototype.encode = function (ixName, ix) {
        switch (ixName) {
            case "initialize": {
                return encodeInitialize(ix);
            }
            case "postVaa": {
                return encodePostVaa(ix);
            }
            case "setFees": {
                return encodeSetFees(ix);
            }
            case "transferFees": {
                return encodeTransferFees(ix);
            }
            case "upgradeContract": {
                return encodeUpgradeContract(ix);
            }
            case "upgradeGuardianSet": {
                return encodeUpgradeGuardianSet(ix);
            }
            case "verifySignatures": {
                return encodeVerifySignatures(ix);
            }
            default: {
                throw new Error("Invalid instruction: " + ixName);
            }
        }
    };
    WormholeInstructionCoder.prototype.encodeState = function (_ixName, _ix) {
        throw new Error("Wormhole program does not have state");
    };
    return WormholeInstructionCoder;
}());
exports.WormholeInstructionCoder = WormholeInstructionCoder;
/** Solitaire enum of existing the Core Bridge's instructions.
 *
 * https://github.com/certusone/wormhole/blob/main/solana/bridge/program/src/lib.rs#L92
 */
var WormholeInstruction;
(function (WormholeInstruction) {
    WormholeInstruction[WormholeInstruction["Initialize"] = 0] = "Initialize";
    WormholeInstruction[WormholeInstruction["PostMessage"] = 1] = "PostMessage";
    WormholeInstruction[WormholeInstruction["PostVAA"] = 2] = "PostVAA";
    WormholeInstruction[WormholeInstruction["SetFees"] = 3] = "SetFees";
    WormholeInstruction[WormholeInstruction["TransferFees"] = 4] = "TransferFees";
    WormholeInstruction[WormholeInstruction["UpgradeContract"] = 5] = "UpgradeContract";
    WormholeInstruction[WormholeInstruction["UpgradeGuardianSet"] = 6] = "UpgradeGuardianSet";
    WormholeInstruction[WormholeInstruction["VerifySignatures"] = 7] = "VerifySignatures";
    WormholeInstruction[WormholeInstruction["PostMessageUnreliable"] = 8] = "PostMessageUnreliable";
})(WormholeInstruction = exports.WormholeInstruction || (exports.WormholeInstruction = {}));
function encodeInitialize(_a) {
    var guardianSetExpirationTime = _a.guardianSetExpirationTime, fee = _a.fee, initialGuardians = _a.initialGuardians;
    if (typeof fee != "bigint") {
        fee = BigInt(fee);
    }
    var initialGuardiansLen = initialGuardians.length;
    var serialized = Buffer.alloc(16 + initialGuardiansLen * utils_1.ETHEREUM_KEY_LENGTH);
    serialized.writeUInt32LE(guardianSetExpirationTime, 0);
    serialized.writeBigUInt64LE(fee, 4);
    serialized.writeUInt32LE(initialGuardiansLen, 12);
    for (var i = 0; i < initialGuardiansLen; ++i) {
        var key = initialGuardians.at(i);
        if (!Buffer.isBuffer(key)) {
            throw new Error("key must be Buffer");
        }
        serialized.write(key.toString("hex"), 16 + i * utils_1.ETHEREUM_KEY_LENGTH, "hex");
    }
    return encodeWormholeInstructionData(WormholeInstruction.Initialize, serialized);
}
function encodeWormholeInstructionData(instructionType, data) {
    var instructionData = Buffer.alloc(1 + (data === undefined ? 0 : data.length));
    instructionData.writeUInt8(instructionType, 0);
    if (data !== undefined) {
        instructionData.write(data.toString("hex"), 1, "hex");
    }
    return instructionData;
}
function encodePostVaa(_a) {
    var version = _a.version, guardianSetIndex = _a.guardianSetIndex, timestamp = _a.timestamp, nonce = _a.nonce, emitterChain = _a.emitterChain, emitterAddress = _a.emitterAddress, sequence = _a.sequence, consistencyLevel = _a.consistencyLevel, payload = _a.payload;
    if (!Buffer.isBuffer(emitterAddress)) {
        throw new Error("emitterAddress must be Buffer");
    }
    if (!Buffer.isBuffer(payload)) {
        throw new Error("payload must be Buffer");
    }
    if (typeof sequence != "bigint") {
        sequence = BigInt(sequence);
    }
    var serialized = Buffer.alloc(60 + payload.length);
    serialized.writeUInt8(version, 0);
    serialized.writeUInt32LE(guardianSetIndex, 1);
    serialized.writeUInt32LE(timestamp, 5);
    serialized.writeUInt32LE(nonce, 9);
    serialized.writeUInt16LE(emitterChain, 13);
    serialized.write(emitterAddress.toString("hex"), 15, "hex");
    serialized.writeBigInt64LE(sequence, 47);
    serialized.writeUInt8(consistencyLevel, 55);
    serialized.writeUInt32LE(payload.length, 56);
    serialized.write(payload.toString("hex"), 60, "hex");
    return encodeWormholeInstructionData(WormholeInstruction.PostVAA, serialized);
}
function encodeSetFees(_a) {
    return encodeWormholeInstructionData(WormholeInstruction.SetFees);
}
function encodeTransferFees(_a) {
    return encodeWormholeInstructionData(WormholeInstruction.TransferFees);
}
function encodeUpgradeContract(_a) {
    return encodeWormholeInstructionData(WormholeInstruction.UpgradeContract);
}
function encodeUpgradeGuardianSet(_a) {
    return encodeWormholeInstructionData(WormholeInstruction.UpgradeGuardianSet);
}
function encodeVerifySignatures(_a) {
    var signatureStatus = _a.signatureStatus;
    return encodeWormholeInstructionData(WormholeInstruction.VerifySignatures, Buffer.from(signatureStatus, "hex"));
}
