/**
 * 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 {
  assertAccountExists,
  assertAccountsExist,
  combineCodec,
  decodeAccount,
  fetchEncodedAccount,
  fetchEncodedAccounts,
  fixDecoderSize,
  fixEncoderSize,
  getAddressDecoder,
  getAddressEncoder,
  getArrayDecoder,
  getArrayEncoder,
  getBytesDecoder,
  getBytesEncoder,
  getStructDecoder,
  getStructEncoder,
  getU128Decoder,
  getU128Encoder,
  getU64Decoder,
  getU64Encoder,
  transformEncoder,
  type Account,
  type Address,
  type EncodedAccount,
  type FetchAccountConfig,
  type FetchAccountsConfig,
  type FixedSizeCodec,
  type FixedSizeDecoder,
  type FixedSizeEncoder,
  type MaybeAccount,
  type MaybeEncodedAccount,
  type ReadonlyUint8Array,
} from "@solana/kit";

export const GLOBAL_CONFIG_DISCRIMINATOR = new Uint8Array([
  149, 8, 156, 202, 160, 252, 176, 217,
]);

export function getGlobalConfigDiscriminatorBytes() {
  return fixEncoderSize(getBytesEncoder(), 8).encode(
    GLOBAL_CONFIG_DISCRIMINATOR,
  );
}

export type GlobalConfig = {
  discriminator: ReadonlyUint8Array;
  globalAdmin: Address;
  treasuryFeeBps: bigint;
  treasuryVaultsAuthority: Address;
  treasuryVaultsAuthorityBump: bigint;
  pendingGlobalAdmin: Address;
  padding1: Array<bigint>;
};

export type GlobalConfigArgs = {
  globalAdmin: Address;
  treasuryFeeBps: number | bigint;
  treasuryVaultsAuthority: Address;
  treasuryVaultsAuthorityBump: number | bigint;
  pendingGlobalAdmin: Address;
  padding1: Array<number | bigint>;
};

/** Gets the encoder for {@link GlobalConfigArgs} account data. */
export function getGlobalConfigEncoder(): FixedSizeEncoder<GlobalConfigArgs> {
  return transformEncoder(
    getStructEncoder([
      ["discriminator", fixEncoderSize(getBytesEncoder(), 8)],
      ["globalAdmin", getAddressEncoder()],
      ["treasuryFeeBps", getU64Encoder()],
      ["treasuryVaultsAuthority", getAddressEncoder()],
      ["treasuryVaultsAuthorityBump", getU64Encoder()],
      ["pendingGlobalAdmin", getAddressEncoder()],
      ["padding1", getArrayEncoder(getU128Encoder(), { size: 126 })],
    ]),
    (value) => ({ ...value, discriminator: GLOBAL_CONFIG_DISCRIMINATOR }),
  );
}

/** Gets the decoder for {@link GlobalConfig} account data. */
export function getGlobalConfigDecoder(): FixedSizeDecoder<GlobalConfig> {
  return getStructDecoder([
    ["discriminator", fixDecoderSize(getBytesDecoder(), 8)],
    ["globalAdmin", getAddressDecoder()],
    ["treasuryFeeBps", getU64Decoder()],
    ["treasuryVaultsAuthority", getAddressDecoder()],
    ["treasuryVaultsAuthorityBump", getU64Decoder()],
    ["pendingGlobalAdmin", getAddressDecoder()],
    ["padding1", getArrayDecoder(getU128Decoder(), { size: 126 })],
  ]);
}

/** Gets the codec for {@link GlobalConfig} account data. */
export function getGlobalConfigCodec(): FixedSizeCodec<
  GlobalConfigArgs,
  GlobalConfig
> {
  return combineCodec(getGlobalConfigEncoder(), getGlobalConfigDecoder());
}

export function decodeGlobalConfig<TAddress extends string = string>(
  encodedAccount: EncodedAccount<TAddress>,
): Account<GlobalConfig, TAddress>;
export function decodeGlobalConfig<TAddress extends string = string>(
  encodedAccount: MaybeEncodedAccount<TAddress>,
): MaybeAccount<GlobalConfig, TAddress>;
export function decodeGlobalConfig<TAddress extends string = string>(
  encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>,
): Account<GlobalConfig, TAddress> | MaybeAccount<GlobalConfig, TAddress> {
  return decodeAccount(
    encodedAccount as MaybeEncodedAccount<TAddress>,
    getGlobalConfigDecoder(),
  );
}

export async function fetchGlobalConfig<TAddress extends string = string>(
  rpc: Parameters<typeof fetchEncodedAccount>[0],
  address: Address<TAddress>,
  config?: FetchAccountConfig,
): Promise<Account<GlobalConfig, TAddress>> {
  const maybeAccount = await fetchMaybeGlobalConfig(rpc, address, config);
  assertAccountExists(maybeAccount);
  return maybeAccount;
}

export async function fetchMaybeGlobalConfig<TAddress extends string = string>(
  rpc: Parameters<typeof fetchEncodedAccount>[0],
  address: Address<TAddress>,
  config?: FetchAccountConfig,
): Promise<MaybeAccount<GlobalConfig, TAddress>> {
  const maybeAccount = await fetchEncodedAccount(rpc, address, config);
  return decodeGlobalConfig(maybeAccount);
}

export async function fetchAllGlobalConfig(
  rpc: Parameters<typeof fetchEncodedAccounts>[0],
  addresses: Array<Address>,
  config?: FetchAccountsConfig,
): Promise<Account<GlobalConfig>[]> {
  const maybeAccounts = await fetchAllMaybeGlobalConfig(rpc, addresses, config);
  assertAccountsExist(maybeAccounts);
  return maybeAccounts;
}

export async function fetchAllMaybeGlobalConfig(
  rpc: Parameters<typeof fetchEncodedAccounts>[0],
  addresses: Array<Address>,
  config?: FetchAccountsConfig,
): Promise<MaybeAccount<GlobalConfig>[]> {
  const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
  return maybeAccounts.map((maybeAccount) => decodeGlobalConfig(maybeAccount));
}

export function getGlobalConfigSize(): number {
  return 2136;
}
