/**
 * This code was AUTOGENERATED using the Codama library.
 * Please DO NOT EDIT THIS FILE, instead use visitors
 * to add features, then rerun Codama to update it.
 *
 * @see https://github.com/codama-idl/codama
 */

import {
  combineCodec,
  fixDecoderSize,
  fixEncoderSize,
  getAddressDecoder,
  getAddressEncoder,
  getBytesDecoder,
  getBytesEncoder,
  getStructDecoder,
  getStructEncoder,
  getU64Decoder,
  getU64Encoder,
  transformEncoder,
  type AccountMeta,
  type Address,
  type FixedSizeCodec,
  type FixedSizeDecoder,
  type FixedSizeEncoder,
  type Instruction,
  type InstructionWithAccounts,
  type InstructionWithData,
  type ReadonlyUint8Array,
} from "@solana/kit";
import { SVM_SPOKE_PROGRAM_ADDRESS } from "../programs";

export const GET_UNSAFE_DEPOSIT_ID_DISCRIMINATOR = new Uint8Array([
  118, 10, 135, 0, 168, 243, 223, 117,
]);

export function getGetUnsafeDepositIdDiscriminatorBytes() {
  return fixEncoderSize(getBytesEncoder(), 8).encode(
    GET_UNSAFE_DEPOSIT_ID_DISCRIMINATOR,
  );
}

export type GetUnsafeDepositIdInstruction<
  TProgram extends string = typeof SVM_SPOKE_PROGRAM_ADDRESS,
  TRemainingAccounts extends readonly AccountMeta<string>[] = [],
> = Instruction<TProgram> &
  InstructionWithData<ReadonlyUint8Array> &
  InstructionWithAccounts<TRemainingAccounts>;

export type GetUnsafeDepositIdInstructionData = {
  discriminator: ReadonlyUint8Array;
  signer: Address;
  depositor: Address;
  depositNonce: bigint;
};

export type GetUnsafeDepositIdInstructionDataArgs = {
  signer: Address;
  depositor: Address;
  depositNonce: number | bigint;
};

export function getGetUnsafeDepositIdInstructionDataEncoder(): FixedSizeEncoder<GetUnsafeDepositIdInstructionDataArgs> {
  return transformEncoder(
    getStructEncoder([
      ["discriminator", fixEncoderSize(getBytesEncoder(), 8)],
      ["signer", getAddressEncoder()],
      ["depositor", getAddressEncoder()],
      ["depositNonce", getU64Encoder()],
    ]),
    (value) => ({
      ...value,
      discriminator: GET_UNSAFE_DEPOSIT_ID_DISCRIMINATOR,
    }),
  );
}

export function getGetUnsafeDepositIdInstructionDataDecoder(): FixedSizeDecoder<GetUnsafeDepositIdInstructionData> {
  return getStructDecoder([
    ["discriminator", fixDecoderSize(getBytesDecoder(), 8)],
    ["signer", getAddressDecoder()],
    ["depositor", getAddressDecoder()],
    ["depositNonce", getU64Decoder()],
  ]);
}

export function getGetUnsafeDepositIdInstructionDataCodec(): FixedSizeCodec<
  GetUnsafeDepositIdInstructionDataArgs,
  GetUnsafeDepositIdInstructionData
> {
  return combineCodec(
    getGetUnsafeDepositIdInstructionDataEncoder(),
    getGetUnsafeDepositIdInstructionDataDecoder(),
  );
}

export type GetUnsafeDepositIdInput = {
  signer: GetUnsafeDepositIdInstructionDataArgs["signer"];
  depositor: GetUnsafeDepositIdInstructionDataArgs["depositor"];
  depositNonce: GetUnsafeDepositIdInstructionDataArgs["depositNonce"];
};

export function getGetUnsafeDepositIdInstruction<
  TProgramAddress extends Address = typeof SVM_SPOKE_PROGRAM_ADDRESS,
>(
  input: GetUnsafeDepositIdInput,
  config?: { programAddress?: TProgramAddress },
): GetUnsafeDepositIdInstruction<TProgramAddress> {
  // Program address.
  const programAddress = config?.programAddress ?? SVM_SPOKE_PROGRAM_ADDRESS;

  // Original args.
  const args = { ...input };

  return Object.freeze({
    data: getGetUnsafeDepositIdInstructionDataEncoder().encode(
      args as GetUnsafeDepositIdInstructionDataArgs,
    ),
    programAddress,
  } as GetUnsafeDepositIdInstruction<TProgramAddress>);
}

export type ParsedGetUnsafeDepositIdInstruction<
  TProgram extends string = typeof SVM_SPOKE_PROGRAM_ADDRESS,
> = {
  programAddress: Address<TProgram>;
  data: GetUnsafeDepositIdInstructionData;
};

export function parseGetUnsafeDepositIdInstruction<TProgram extends string>(
  instruction: Instruction<TProgram> & InstructionWithData<ReadonlyUint8Array>,
): ParsedGetUnsafeDepositIdInstruction<TProgram> {
  return {
    programAddress: instruction.programAddress,
    data: getGetUnsafeDepositIdInstructionDataDecoder().decode(
      instruction.data,
    ),
  };
}
