import { __awaiter, __generator } from "tslib";
import { Transaction, sendAndConfirmTransaction, PublicKey } from "@solana/web3.js";
import { LargeAccountsCoder } from "./coders";
/**
 * Loads execute relayer refund leaf parameters.
 */
export function loadExecuteRelayerRefundLeafParams(program, caller, rootBundleId, relayerRefundLeaf, proof) {
    return __awaiter(this, void 0, void 0, function () {
        var maxInstructionParamsFragment, instructionParams, accountInfo, accountCoder, instructionParamsBytes, i, fragment;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    maxInstructionParamsFragment = 900;
                    instructionParams = PublicKey.findProgramAddressSync([Buffer.from("instruction_params"), caller.toBuffer()], program.programId)[0];
                    return [4 /*yield*/, program.provider.connection.getAccountInfo(instructionParams)];
                case 1:
                    accountInfo = _a.sent();
                    if (!(accountInfo !== null)) return [3 /*break*/, 3];
                    return [4 /*yield*/, program.methods.closeInstructionParams().rpc()];
                case 2:
                    _a.sent();
                    _a.label = 3;
                case 3:
                    accountCoder = new LargeAccountsCoder(program.idl);
                    return [4 /*yield*/, accountCoder.encode("executeRelayerRefundLeafParams", {
                            rootBundleId: rootBundleId,
                            relayerRefundLeaf: relayerRefundLeaf,
                            proof: proof,
                        })];
                case 4:
                    instructionParamsBytes = _a.sent();
                    return [4 /*yield*/, program.methods.initializeInstructionParams(instructionParamsBytes.length).rpc()];
                case 5:
                    _a.sent();
                    i = 0;
                    _a.label = 6;
                case 6:
                    if (!(i < instructionParamsBytes.length)) return [3 /*break*/, 9];
                    fragment = instructionParamsBytes.slice(i, i + maxInstructionParamsFragment);
                    return [4 /*yield*/, program.methods.writeInstructionParamsFragment(i, fragment).rpc()];
                case 7:
                    _a.sent();
                    _a.label = 8;
                case 8:
                    i += maxInstructionParamsFragment;
                    return [3 /*break*/, 6];
                case 9: return [2 /*return*/, instructionParams];
            }
        });
    });
}
/**
 * Closes the instruction parameters account.
 */
export function closeInstructionParams(program, signer) {
    return __awaiter(this, void 0, void 0, function () {
        var instructionParams, accountInfo, closeIx;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    instructionParams = PublicKey.findProgramAddressSync([Buffer.from("instruction_params"), signer.publicKey.toBuffer()], program.programId)[0];
                    return [4 /*yield*/, program.provider.connection.getAccountInfo(instructionParams)];
                case 1:
                    accountInfo = _a.sent();
                    if (!(accountInfo !== null)) return [3 /*break*/, 4];
                    return [4 /*yield*/, program.methods.closeInstructionParams().accounts({ signer: signer.publicKey }).instruction()];
                case 2:
                    closeIx = _a.sent();
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    return [4 /*yield*/, sendAndConfirmTransaction(program.provider.connection, new Transaction().add(closeIx), [signer])];
                case 3:
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    _a.sent();
                    _a.label = 4;
                case 4: return [2 /*return*/];
            }
        });
    });
}
/**
 * Creates instructions to load fill relay parameters.
 */
export function createFillRelayParamsInstructions(program, signer, relayData, repaymentChainId, repaymentAddress) {
    return __awaiter(this, void 0, void 0, function () {
        var maxInstructionParamsFragment, accountCoder, instructionParamsBytes, loadInstructions, _a, _b, i, fragment, _c, _d, closeInstruction;
        return __generator(this, function (_e) {
            switch (_e.label) {
                case 0:
                    maxInstructionParamsFragment = 900;
                    accountCoder = new LargeAccountsCoder(program.idl);
                    return [4 /*yield*/, accountCoder.encode("fillRelayParams", {
                            relayData: relayData,
                            repaymentChainId: repaymentChainId,
                            repaymentAddress: repaymentAddress,
                        })];
                case 1:
                    instructionParamsBytes = _e.sent();
                    loadInstructions = [];
                    _b = (_a = loadInstructions).push;
                    return [4 /*yield*/, program.methods.initializeInstructionParams(instructionParamsBytes.length).accounts({ signer: signer }).instruction()];
                case 2:
                    _b.apply(_a, [_e.sent()]);
                    i = 0;
                    _e.label = 3;
                case 3:
                    if (!(i < instructionParamsBytes.length)) return [3 /*break*/, 6];
                    fragment = instructionParamsBytes.slice(i, i + maxInstructionParamsFragment);
                    _d = (_c = loadInstructions).push;
                    return [4 /*yield*/, program.methods.writeInstructionParamsFragment(i, fragment).accounts({ signer: signer }).instruction()];
                case 4:
                    _d.apply(_c, [_e.sent()]);
                    _e.label = 5;
                case 5:
                    i += maxInstructionParamsFragment;
                    return [3 /*break*/, 3];
                case 6: return [4 /*yield*/, program.methods.closeInstructionParams().accounts({ signer: signer }).instruction()];
                case 7:
                    closeInstruction = _e.sent();
                    return [2 /*return*/, { loadInstructions: loadInstructions, closeInstruction: closeInstruction }];
            }
        });
    });
}
/**
 * Loads fill relay parameters.
 */
export function loadFillRelayParams(program, signer, relayData, repaymentChainId, repaymentAddress) {
    return __awaiter(this, void 0, void 0, function () {
        var loadInstructions, i;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: 
                // Close the instruction params account if the caller has used it before.
                return [4 /*yield*/, closeInstructionParams(program, signer)];
                case 1:
                    // Close the instruction params account if the caller has used it before.
                    _a.sent();
                    return [4 /*yield*/, createFillRelayParamsInstructions(program, signer.publicKey, relayData, repaymentChainId, repaymentAddress)];
                case 2:
                    loadInstructions = (_a.sent()).loadInstructions;
                    i = 0;
                    _a.label = 3;
                case 3:
                    if (!(i < loadInstructions.length)) return [3 /*break*/, 6];
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    return [4 /*yield*/, sendAndConfirmTransaction(program.provider.connection, new Transaction().add(loadInstructions[i]), [
                            signer,
                        ])];
                case 4:
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    _a.sent();
                    _a.label = 5;
                case 5:
                    i += 1;
                    return [3 /*break*/, 3];
                case 6: return [2 /*return*/];
            }
        });
    });
}
/**
 * Loads request slow fill parameters.
 */
export function loadRequestSlowFillParams(program, signer, relayData) {
    return __awaiter(this, void 0, void 0, function () {
        var maxInstructionParamsFragment, accountCoder, instructionParamsBytes, loadInstructions, _a, _b, i, fragment, _c, _d;
        return __generator(this, function (_e) {
            switch (_e.label) {
                case 0: 
                // Close the instruction params account if the caller has used it before.
                return [4 /*yield*/, closeInstructionParams(program, signer)];
                case 1:
                    // Close the instruction params account if the caller has used it before.
                    _e.sent();
                    maxInstructionParamsFragment = 900;
                    accountCoder = new LargeAccountsCoder(program.idl);
                    return [4 /*yield*/, accountCoder.encode("requestSlowFillParams", { relayData: relayData })];
                case 2:
                    instructionParamsBytes = _e.sent();
                    loadInstructions = [];
                    _b = (_a = loadInstructions).push;
                    return [4 /*yield*/, program.methods
                            .initializeInstructionParams(instructionParamsBytes.length)
                            .accounts({ signer: signer.publicKey })
                            .instruction()];
                case 3:
                    _b.apply(_a, [_e.sent()]);
                    i = 0;
                    _e.label = 4;
                case 4:
                    if (!(i < instructionParamsBytes.length)) return [3 /*break*/, 7];
                    fragment = instructionParamsBytes.slice(i, i + maxInstructionParamsFragment);
                    _d = (_c = loadInstructions).push;
                    return [4 /*yield*/, program.methods
                            .writeInstructionParamsFragment(i, fragment)
                            .accounts({ signer: signer.publicKey })
                            .instruction()];
                case 5:
                    _d.apply(_c, [_e.sent()]);
                    _e.label = 6;
                case 6:
                    i += maxInstructionParamsFragment;
                    return [3 /*break*/, 4];
                case 7: return [2 /*return*/, loadInstructions];
            }
        });
    });
}
/**
 * Loads execute slow relay leaf parameters.
 */
export function loadExecuteSlowRelayLeafParams(program, signer, slowFillLeaf, rootBundleId, proof) {
    return __awaiter(this, void 0, void 0, function () {
        var maxInstructionParamsFragment, accountCoder, instructionParamsBytes, loadInstructions, _a, _b, i, fragment, _c, _d;
        return __generator(this, function (_e) {
            switch (_e.label) {
                case 0: 
                // Close the instruction params account if the caller has used it before.
                return [4 /*yield*/, closeInstructionParams(program, signer)];
                case 1:
                    // Close the instruction params account if the caller has used it before.
                    _e.sent();
                    maxInstructionParamsFragment = 900;
                    accountCoder = new LargeAccountsCoder(program.idl);
                    return [4 /*yield*/, accountCoder.encode("executeSlowRelayLeafParams", {
                            slowFillLeaf: slowFillLeaf,
                            rootBundleId: rootBundleId,
                            proof: proof,
                        })];
                case 2:
                    instructionParamsBytes = _e.sent();
                    loadInstructions = [];
                    _b = (_a = loadInstructions).push;
                    return [4 /*yield*/, program.methods
                            .initializeInstructionParams(instructionParamsBytes.length)
                            .accounts({ signer: signer.publicKey })
                            .instruction()];
                case 3:
                    _b.apply(_a, [_e.sent()]);
                    i = 0;
                    _e.label = 4;
                case 4:
                    if (!(i < instructionParamsBytes.length)) return [3 /*break*/, 7];
                    fragment = instructionParamsBytes.slice(i, i + maxInstructionParamsFragment);
                    _d = (_c = loadInstructions).push;
                    return [4 /*yield*/, program.methods
                            .writeInstructionParamsFragment(i, fragment)
                            .accounts({ signer: signer.publicKey })
                            .instruction()];
                case 5:
                    _d.apply(_c, [_e.sent()]);
                    _e.label = 6;
                case 6:
                    i += maxInstructionParamsFragment;
                    return [3 /*break*/, 4];
                case 7: return [2 /*return*/, loadInstructions];
            }
        });
    });
}
//# sourceMappingURL=instructionParamsUtils.js.map