/**
 * 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 {
  assertIsInstructionWithAccounts,
  containsBytes,
  fixEncoderSize,
  getBytesEncoder,
  type Address,
  type Instruction,
  type InstructionWithData,
  type ReadonlyUint8Array,
} from "@solana/kit";
import {
  parseAcceptOwnershipInstruction,
  parseDisableAttesterInstruction,
  parseEnableAttesterInstruction,
  parseInitializeInstruction,
  parseIsNonceUsedInstruction,
  parsePauseInstruction,
  parseReceiveMessageInstruction,
  parseReclaimEventAccountInstruction,
  parseSendMessageInstruction,
  parseSetMaxMessageBodySizeInstruction,
  parseSetSignatureThresholdInstruction,
  parseTransferOwnershipInstruction,
  parseUnpauseInstruction,
  parseUpdateAttesterManagerInstruction,
  parseUpdatePauserInstruction,
  type ParsedAcceptOwnershipInstruction,
  type ParsedDisableAttesterInstruction,
  type ParsedEnableAttesterInstruction,
  type ParsedInitializeInstruction,
  type ParsedIsNonceUsedInstruction,
  type ParsedPauseInstruction,
  type ParsedReceiveMessageInstruction,
  type ParsedReclaimEventAccountInstruction,
  type ParsedSendMessageInstruction,
  type ParsedSetMaxMessageBodySizeInstruction,
  type ParsedSetSignatureThresholdInstruction,
  type ParsedTransferOwnershipInstruction,
  type ParsedUnpauseInstruction,
  type ParsedUpdateAttesterManagerInstruction,
  type ParsedUpdatePauserInstruction,
} from "../instructions";

export const MESSAGE_TRANSMITTER_V2_PROGRAM_ADDRESS =
  "CCTPV2Sm4AdWt5296sk4P66VBZ7bEhcARwFaaS9YPbeC" as Address<"CCTPV2Sm4AdWt5296sk4P66VBZ7bEhcARwFaaS9YPbeC">;

export enum MessageTransmitterV2Account {
  MessageSent,
  MessageTransmitter,
  UsedNonce,
}

export function identifyMessageTransmitterV2Account(
  account: { data: ReadonlyUint8Array } | ReadonlyUint8Array,
): MessageTransmitterV2Account {
  const data = "data" in account ? account.data : account;
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([131, 100, 133, 56, 166, 225, 151, 60]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Account.MessageSent;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([71, 40, 180, 142, 19, 203, 35, 252]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Account.MessageTransmitter;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([212, 222, 157, 252, 130, 71, 179, 238]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Account.UsedNonce;
  }
  throw new Error(
    "The provided account could not be identified as a messageTransmitterV2 account.",
  );
}

export enum MessageTransmitterV2Instruction {
  AcceptOwnership,
  DisableAttester,
  EnableAttester,
  Initialize,
  IsNonceUsed,
  Pause,
  ReceiveMessage,
  ReclaimEventAccount,
  SendMessage,
  SetMaxMessageBodySize,
  SetSignatureThreshold,
  TransferOwnership,
  Unpause,
  UpdateAttesterManager,
  UpdatePauser,
}

export function identifyMessageTransmitterV2Instruction(
  instruction: { data: ReadonlyUint8Array } | ReadonlyUint8Array,
): MessageTransmitterV2Instruction {
  const data = "data" in instruction ? instruction.data : instruction;
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([172, 23, 43, 13, 238, 213, 85, 150]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.AcceptOwnership;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([61, 171, 131, 95, 172, 15, 227, 229]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.DisableAttester;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([2, 11, 193, 115, 5, 148, 4, 198]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.EnableAttester;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([175, 175, 109, 31, 13, 152, 155, 237]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.Initialize;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([144, 72, 107, 148, 35, 218, 31, 187]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.IsNonceUsed;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([211, 22, 221, 251, 74, 121, 193, 47]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.Pause;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([38, 144, 127, 225, 31, 225, 238, 25]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.ReceiveMessage;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([94, 198, 180, 159, 131, 236, 15, 174]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.ReclaimEventAccount;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([57, 40, 34, 178, 189, 10, 65, 26]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.SendMessage;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([168, 178, 8, 117, 217, 167, 219, 31]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.SetMaxMessageBodySize;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([163, 19, 154, 168, 82, 209, 214, 219]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.SetSignatureThreshold;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([65, 177, 215, 73, 53, 45, 99, 47]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.TransferOwnership;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([169, 144, 4, 38, 10, 141, 188, 255]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.Unpause;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([175, 245, 178, 104, 85, 179, 71, 16]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.UpdateAttesterManager;
  }
  if (
    containsBytes(
      data,
      fixEncoderSize(getBytesEncoder(), 8).encode(
        new Uint8Array([140, 171, 211, 132, 57, 201, 16, 254]),
      ),
      0,
    )
  ) {
    return MessageTransmitterV2Instruction.UpdatePauser;
  }
  throw new Error(
    "The provided instruction could not be identified as a messageTransmitterV2 instruction.",
  );
}

export type ParsedMessageTransmitterV2Instruction<
  TProgram extends string = "CCTPV2Sm4AdWt5296sk4P66VBZ7bEhcARwFaaS9YPbeC",
> =
  | ({
      instructionType: MessageTransmitterV2Instruction.AcceptOwnership;
    } & ParsedAcceptOwnershipInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.DisableAttester;
    } & ParsedDisableAttesterInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.EnableAttester;
    } & ParsedEnableAttesterInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.Initialize;
    } & ParsedInitializeInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.IsNonceUsed;
    } & ParsedIsNonceUsedInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.Pause;
    } & ParsedPauseInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.ReceiveMessage;
    } & ParsedReceiveMessageInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.ReclaimEventAccount;
    } & ParsedReclaimEventAccountInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.SendMessage;
    } & ParsedSendMessageInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.SetMaxMessageBodySize;
    } & ParsedSetMaxMessageBodySizeInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.SetSignatureThreshold;
    } & ParsedSetSignatureThresholdInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.TransferOwnership;
    } & ParsedTransferOwnershipInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.Unpause;
    } & ParsedUnpauseInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.UpdateAttesterManager;
    } & ParsedUpdateAttesterManagerInstruction<TProgram>)
  | ({
      instructionType: MessageTransmitterV2Instruction.UpdatePauser;
    } & ParsedUpdatePauserInstruction<TProgram>);

export function parseMessageTransmitterV2Instruction<TProgram extends string>(
  instruction: Instruction<TProgram> & InstructionWithData<ReadonlyUint8Array>,
): ParsedMessageTransmitterV2Instruction<TProgram> {
  const instructionType = identifyMessageTransmitterV2Instruction(instruction);
  switch (instructionType) {
    case MessageTransmitterV2Instruction.AcceptOwnership: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.AcceptOwnership,
        ...parseAcceptOwnershipInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.DisableAttester: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.DisableAttester,
        ...parseDisableAttesterInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.EnableAttester: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.EnableAttester,
        ...parseEnableAttesterInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.Initialize: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.Initialize,
        ...parseInitializeInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.IsNonceUsed: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.IsNonceUsed,
        ...parseIsNonceUsedInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.Pause: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.Pause,
        ...parsePauseInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.ReceiveMessage: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.ReceiveMessage,
        ...parseReceiveMessageInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.ReclaimEventAccount: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.ReclaimEventAccount,
        ...parseReclaimEventAccountInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.SendMessage: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.SendMessage,
        ...parseSendMessageInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.SetMaxMessageBodySize: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.SetMaxMessageBodySize,
        ...parseSetMaxMessageBodySizeInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.SetSignatureThreshold: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.SetSignatureThreshold,
        ...parseSetSignatureThresholdInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.TransferOwnership: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.TransferOwnership,
        ...parseTransferOwnershipInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.Unpause: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.Unpause,
        ...parseUnpauseInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.UpdateAttesterManager: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.UpdateAttesterManager,
        ...parseUpdateAttesterManagerInstruction(instruction),
      };
    }
    case MessageTransmitterV2Instruction.UpdatePauser: {
      assertIsInstructionWithAccounts(instruction);
      return {
        instructionType: MessageTransmitterV2Instruction.UpdatePauser,
        ...parseUpdatePauserInstruction(instruction),
      };
    }
    default:
      throw new Error(
        `Unrecognized instruction type: ${instructionType as string}`,
      );
  }
}
