// file: kb_lib/src/dex_decode_context.rs

//! Transaction context loading for DEX decoding.
//!
//! This module loads the persisted transaction and projected instructions
//! required by `DexDecodeService`.

/// Transaction context required by DEX decoding.
pub(crate) struct DexDecodeTransactionContext {
    /// Persisted chain transaction.
    pub(crate) transaction: crate::ChainTransactionDto,
    /// Projected transaction instructions.
    pub(crate) instructions: std::vec::Vec<crate::ChainInstructionDto>,
}

/// Loads the transaction and its projected instructions for DEX decoding.
pub(crate) async fn load_dex_decode_transaction_context(
    database: &crate::Database,
    signature: &str,
) -> Result<crate::dex_decode_context::DexDecodeTransactionContext, crate::Error> {
    let transaction_result =
        crate::query_chain_transactions_get_by_signature(database, signature).await;
    let transaction_option = match transaction_result {
        Ok(transaction_option) => transaction_option,
        Err(error) => return Err(error),
    };
    let transaction = match transaction_option {
        Some(transaction) => transaction,
        None => {
            return Err(crate::Error::InvalidState(format!(
                "cannot decode unknown chain transaction '{}'",
                signature
            )));
        },
    };
    let transaction_id = match transaction.id {
        Some(transaction_id) => transaction_id,
        None => {
            return Err(crate::Error::InvalidState(format!(
                "chain transaction '{}' has no internal id",
                signature
            )));
        },
    };
    let instructions_result =
        crate::query_chain_instructions_list_by_transaction_id(database, transaction_id).await;
    let instructions = match instructions_result {
        Ok(instructions) => instructions,
        Err(error) => return Err(error),
    };
    return Ok(crate::dex_decode_context::DexDecodeTransactionContext {
        transaction,
        instructions,
    });
}
