//! This code was AUTOGENERATED using the Codama library.

pub use super::super::events;
use carbon_core::{borsh, deserialize::ArrangeAccounts};

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(
    Debug,
    Clone,
    carbon_core::borsh::BorshSerialize,
    carbon_core::borsh::BorshDeserialize,
    PartialEq,
)]
pub enum CpiEvent {
    CollectPersonalFeeEvent(events::collect_personal_fee_event::CollectPersonalFeeEventEvent),
    CollectProtocolFeeEvent(events::collect_protocol_fee_event::CollectProtocolFeeEventEvent),
    ConfigChangeEvent(events::config_change_event::ConfigChangeEventEvent),
    CreatePersonalPositionEvent(
        events::create_personal_position_event::CreatePersonalPositionEventEvent,
    ),
    DecreaseLiquidityEvent(events::decrease_liquidity_event::DecreaseLiquidityEventEvent),
    IncreaseLiquidityEvent(events::increase_liquidity_event::IncreaseLiquidityEventEvent),
    LiquidityCalculateEvent(events::liquidity_calculate_event::LiquidityCalculateEventEvent),
    LiquidityChangeEvent(events::liquidity_change_event::LiquidityChangeEventEvent),
    PoolCreatedEvent(events::pool_created_event::PoolCreatedEventEvent),
    SwapEvent(events::swap_event::SwapEventEvent),
    UpdateRewardInfosEvent(events::update_reward_infos_event::UpdateRewardInfosEventEvent),
}

#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CpiEventInstructionAccounts {
    pub program: solana_pubkey::Pubkey,
    pub event_authority: solana_pubkey::Pubkey,
    pub remaining: Vec<solana_instruction::AccountMeta>,
}

impl CpiEvent {
    pub fn decode(data: &[u8]) -> Option<Self> {
        if data.len() < 8 {
            return None;
        }
        let discriminator = &data[0..8];
        if discriminator != [228, 69, 165, 46, 81, 203, 154, 29] {
            return None;
        }

        let event_data = &data[8..];

        if let Some(decoded) =
            events::collect_personal_fee_event::CollectPersonalFeeEventEvent::decode(event_data)
        {
            return Some(CpiEvent::CollectPersonalFeeEvent(decoded));
        }
        if let Some(decoded) =
            events::collect_protocol_fee_event::CollectProtocolFeeEventEvent::decode(event_data)
        {
            return Some(CpiEvent::CollectProtocolFeeEvent(decoded));
        }
        if let Some(decoded) =
            events::config_change_event::ConfigChangeEventEvent::decode(event_data)
        {
            return Some(CpiEvent::ConfigChangeEvent(decoded));
        }
        if let Some(decoded) =
            events::create_personal_position_event::CreatePersonalPositionEventEvent::decode(
                event_data,
            )
        {
            return Some(CpiEvent::CreatePersonalPositionEvent(decoded));
        }
        if let Some(decoded) =
            events::decrease_liquidity_event::DecreaseLiquidityEventEvent::decode(event_data)
        {
            return Some(CpiEvent::DecreaseLiquidityEvent(decoded));
        }
        if let Some(decoded) =
            events::increase_liquidity_event::IncreaseLiquidityEventEvent::decode(event_data)
        {
            return Some(CpiEvent::IncreaseLiquidityEvent(decoded));
        }
        if let Some(decoded) =
            events::liquidity_calculate_event::LiquidityCalculateEventEvent::decode(event_data)
        {
            return Some(CpiEvent::LiquidityCalculateEvent(decoded));
        }
        if let Some(decoded) =
            events::liquidity_change_event::LiquidityChangeEventEvent::decode(event_data)
        {
            return Some(CpiEvent::LiquidityChangeEvent(decoded));
        }
        if let Some(decoded) = events::pool_created_event::PoolCreatedEventEvent::decode(event_data)
        {
            return Some(CpiEvent::PoolCreatedEvent(decoded));
        }
        if let Some(decoded) = events::swap_event::SwapEventEvent::decode(event_data) {
            return Some(CpiEvent::SwapEvent(decoded));
        }
        if let Some(decoded) =
            events::update_reward_infos_event::UpdateRewardInfosEventEvent::decode(event_data)
        {
            return Some(CpiEvent::UpdateRewardInfosEvent(decoded));
        }
        None
    }
}

impl ArrangeAccounts for CpiEvent {
    type ArrangedAccounts = CpiEventInstructionAccounts;

    fn arrange_accounts(
        accounts: &[solana_instruction::AccountMeta],
    ) -> Option<Self::ArrangedAccounts> {
        match accounts {
            [program, event_authority, remaining @ ..] => Some(CpiEventInstructionAccounts {
                program: program.pubkey,
                event_authority: event_authority.pubkey,
                remaining: remaining.to_vec(),
            }),
            [event_authority] => Some(CpiEventInstructionAccounts {
                program: crate::PROGRAM_ID,
                event_authority: event_authority.pubkey,
                remaining: Vec::new(),
            }),
            _ => None,
        }
    }
}
