//! This code was AUTOGENERATED using the Codama library.
pub mod deposit_all_token_types_row;
pub mod deposit_single_token_type_exact_amount_in_row;
pub mod initialize_row;
pub mod swap_row;
pub mod withdraw_all_token_types_row;
pub mod withdraw_single_token_type_exact_amount_out_row;

pub use self::{
    deposit_all_token_types_row::*, deposit_single_token_type_exact_amount_in_row::*,
    initialize_row::*, swap_row::*, withdraw_all_token_types_row::*,
    withdraw_single_token_type_exact_amount_out_row::*,
};
use super::FluxbeamInstruction;

pub struct FluxbeamInstructionsMigration;

impl sqlx_migrator::Migration<sqlx::Postgres> for FluxbeamInstructionsMigration {
    fn app(&self) -> &str {
        "fluxbeam"
    }

    fn name(&self) -> &str {
        "fluxbeam_instructions"
    }

    fn operations(&self) -> Vec<Box<dyn sqlx_migrator::Operation<sqlx::Postgres>>> {
        vec![
            Box::new(DepositAllTokenTypesMigrationOperation),
            Box::new(DepositSingleTokenTypeExactAmountInMigrationOperation),
            Box::new(InitializeMigrationOperation),
            Box::new(SwapMigrationOperation),
            Box::new(WithdrawAllTokenTypesMigrationOperation),
            Box::new(WithdrawSingleTokenTypeExactAmountOutMigrationOperation),
        ]
    }

    fn parents(&self) -> Vec<Box<dyn sqlx_migrator::Migration<sqlx::Postgres>>> {
        vec![]
    }
}

pub struct FluxbeamInstructionWithMetadata(
    pub FluxbeamInstruction,
    pub carbon_core::instruction::InstructionMetadata,
    pub Vec<solana_instruction::AccountMeta>,
);

impl
    From<(
        FluxbeamInstruction,
        carbon_core::instruction::InstructionMetadata,
        Vec<solana_instruction::AccountMeta>,
    )> for FluxbeamInstructionWithMetadata
{
    fn from(
        value: (
            FluxbeamInstruction,
            carbon_core::instruction::InstructionMetadata,
            Vec<solana_instruction::AccountMeta>,
        ),
    ) -> Self {
        FluxbeamInstructionWithMetadata(value.0, value.1, value.2)
    }
}

#[async_trait::async_trait]
impl carbon_core::postgres::operations::Insert for FluxbeamInstructionWithMetadata {
    async fn insert(&self, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
        let FluxbeamInstructionWithMetadata(decoded_instruction, metadata, raw_accounts) = self;
        match decoded_instruction {
            FluxbeamInstruction::Initialize { data, .. } => {
                let row = initialize_row::InitializeRow::from_parts(
                    data.clone(),
                    metadata.clone(),
                    raw_accounts.clone(),
                );
                row.insert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::Swap { data, .. } => {
                let row = swap_row::SwapRow::from_parts(
                    data.clone(),
                    metadata.clone(),
                    raw_accounts.clone(),
                );
                row.insert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::DepositAllTokenTypes { data, .. } => {
                let row = deposit_all_token_types_row::DepositAllTokenTypesRow::from_parts(
                    data.clone(),
                    metadata.clone(),
                    raw_accounts.clone(),
                );
                row.insert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::WithdrawAllTokenTypes { data, .. } => {
                let row = withdraw_all_token_types_row::WithdrawAllTokenTypesRow::from_parts(
                    data.clone(),
                    metadata.clone(),
                    raw_accounts.clone(),
                );
                row.insert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::DepositSingleTokenTypeExactAmountIn { data, .. } => {
                let row = deposit_single_token_type_exact_amount_in_row::DepositSingleTokenTypeExactAmountInRow::from_parts(data.clone(), metadata.clone(), raw_accounts.clone());
                row.insert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::WithdrawSingleTokenTypeExactAmountOut { data, .. } => {
                let row = withdraw_single_token_type_exact_amount_out_row::WithdrawSingleTokenTypeExactAmountOutRow::from_parts(data.clone(), metadata.clone(), raw_accounts.clone());
                row.insert(pool).await?;
                Ok(())
            }
        }
    }
}

#[async_trait::async_trait]
impl carbon_core::postgres::operations::Upsert for FluxbeamInstructionWithMetadata {
    async fn upsert(&self, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
        let FluxbeamInstructionWithMetadata(decoded_instruction, metadata, raw_accounts) = self;
        match decoded_instruction {
            FluxbeamInstruction::Initialize { data, .. } => {
                let row = initialize_row::InitializeRow::from_parts(
                    data.clone(),
                    metadata.clone(),
                    raw_accounts.clone(),
                );
                row.upsert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::Swap { data, .. } => {
                let row = swap_row::SwapRow::from_parts(
                    data.clone(),
                    metadata.clone(),
                    raw_accounts.clone(),
                );
                row.upsert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::DepositAllTokenTypes { data, .. } => {
                let row = deposit_all_token_types_row::DepositAllTokenTypesRow::from_parts(
                    data.clone(),
                    metadata.clone(),
                    raw_accounts.clone(),
                );
                row.upsert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::WithdrawAllTokenTypes { data, .. } => {
                let row = withdraw_all_token_types_row::WithdrawAllTokenTypesRow::from_parts(
                    data.clone(),
                    metadata.clone(),
                    raw_accounts.clone(),
                );
                row.upsert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::DepositSingleTokenTypeExactAmountIn { data, .. } => {
                let row = deposit_single_token_type_exact_amount_in_row::DepositSingleTokenTypeExactAmountInRow::from_parts(data.clone(), metadata.clone(), raw_accounts.clone());
                row.upsert(pool).await?;
                Ok(())
            }
            FluxbeamInstruction::WithdrawSingleTokenTypeExactAmountOut { data, .. } => {
                let row = withdraw_single_token_type_exact_amount_out_row::WithdrawSingleTokenTypeExactAmountOutRow::from_parts(data.clone(), metadata.clone(), raw_accounts.clone());
                row.upsert(pool).await?;
                Ok(())
            }
        }
    }
}
