use {
    litesvm::LiteSVM, solana_keypair::Keypair as SolanaKeypair,
    solana_pubkey::Pubkey as SolanaPubkey,
};
pub struct SvmContext {
    pub svm: LiteSVM,
    pub named_actors: Vec<(String, SolanaKeypair)>,
    pub named_accounts: Vec<(String, SolanaPubkey)>,
    pub named_programs: Vec<(String, SolanaPubkey)>,
}

impl SvmContext {
    pub fn new() -> Self {
        Self {
            svm: LiteSVM::new(),
            named_actors: vec![],
            named_accounts: vec![],
            named_programs: vec![],
        }
    }

    /////// ADDING NAMED ITEMS ///////

    pub fn add_actor(&mut self, name: &str, actor: SolanaKeypair) {
        self.named_actors.push((name.to_string(), actor));
    }

    pub fn add_account(&mut self, name: &str, pubkey: SolanaPubkey) {
        self.named_accounts.push((name.to_string(), pubkey));
    }

    pub fn add_program(&mut self, name: &str, pubkey: SolanaPubkey) {
        self.named_programs.push((name.to_string(), pubkey));
    }

    /////// GETTING NAMED ITEMS ///////

    pub fn get_actor(&self, name: &str) -> &SolanaKeypair {
        self.named_actors
            .iter()
            .find(|(n, _)| n == name)
            .map(|(_, p)| p)
            .expect(&format!("Actor '{name}' not found"))
    }

    pub fn get_account_pubkey(&self, name: &str) -> &SolanaPubkey {
        self.named_accounts
            .iter()
            .find(|(n, _)| n == name)
            .map(|(_, p)| p)
            .expect(&format!("Account '{name}' not found"))
    }
}
