#[cfg(feature = "sdk")]
pub mod sdk;

use generated::types::PaymentFeedType;
use solana_program::pubkey;
use solana_program::pubkey::Pubkey;

#[allow(unused)]
#[allow(clippy::identity_op)]
mod generated;

pub use generated::programs::STABLEBOND_ID;
pub use generated::programs::STABLEBOND_ID as ID;
pub use generated::*;

impl AsRef<[u8]> for PaymentFeedType {
    fn as_ref(&self) -> &[u8] {
        match self {
            Self::UsdcUsd => b"usdc_usd",
            Self::UsdcMxn => b"usdc_mxn",
            Self::SwitchboardUsdcUsd => b"switchboard_usdc_usd",
            Self::SwitchboardUsdcMxn => b"switchboard_usdc_mxn",
            Self::Stub => b"stub",
            Self::SwitchboardUsdcBrl => b"switchboard_usdc_brl",
            Self::SwitchboardUsdcEur => b"switchboard_usdc_eur",
            Self::SwitchboardUsdcGbp => b"switchboard_usdc_gbp",
            Self::SwitchboardOnDemandUsdcMxn => b"switchboard_on_demand_usdc_mxn",
            Self::SwitchboardOnDemandUsdcBrl => b"switchboard_on_demand_usdc_brl",
            Self::SwitchboardOnDemandUsdcEur => b"switchboard_on_demand_usdc_eur",
            Self::SwitchboardOnDemandUsdcGbp => b"switchboard_on_demand_usdc_gbp",
            Self::SwitchboardOnDemandUsdcUsd => b"switchboard_on_demand_usdc_usd",
        }
    }
}

pub fn find_config_pda() -> (Pubkey, u8) {
    Pubkey::find_program_address(&["config".to_string().as_ref()], &crate::ID)
}

pub fn find_delegate_pda(delegate_wallet: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["delegate".to_string().as_ref(), delegate_wallet.as_ref()],
        &crate::ID,
    )
}

pub fn find_bond_pda(mint: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(&["bond".to_string().as_ref(), mint.as_ref()], &crate::ID)
}

pub fn find_issuance_pda(bond: Pubkey, issuance_number: u64) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &[
            "issuance".to_string().as_ref(),
            bond.as_ref(),
            &issuance_number.to_le_bytes(),
        ],
        &crate::ID,
    )
}

pub fn find_payment_pda(issuance: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["payment".to_string().as_ref(), issuance.as_ref()],
        &crate::ID,
    )
}

pub fn find_payout_pda(issuance: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["payout".to_string().as_ref(), issuance.as_ref()],
        &crate::ID,
    )
}

pub fn find_payment_feed_pda(payment_feed_type: PaymentFeedType) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &[
            "payment_feed".to_string().as_ref(),
            payment_feed_type.as_ref(),
        ],
        &crate::ID,
    )
}

pub fn find_nft_issuance_vault_pda(nft_mint: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["nft_issuance_vault".to_string().as_ref(), nft_mint.as_ref()],
        &crate::ID,
    )
}

pub fn find_access_pass_pda(user_wallet: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["access_pass".to_string().as_ref(), user_wallet.as_ref()],
        &crate::ID,
    )
}

pub fn find_purchase_order_pda(nft_mint: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["purchase_order".to_string().as_ref(), nft_mint.as_ref()],
        &crate::ID,
    )
}

pub fn find_kyc_pda(user_wallet: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["kyc".to_string().as_ref(), user_wallet.as_ref()],
        &crate::ID,
    )
}

pub fn find_sell_liquidity_pda(bond: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["sell_liquidity".to_string().as_ref(), bond.as_ref()],
        &crate::ID,
    )
}

pub fn find_offramp_pda(external_identifier: &[u8; 16]) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["offramp".to_string().as_ref(), external_identifier.as_ref()],
        &crate::ID,
    )
}

pub fn find_onramp_pda(external_identifier: &[u8; 16]) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["onramp".to_string().as_ref(), external_identifier.as_ref()],
        &crate::ID,
    )
}

pub fn find_bond_multisig_meta_pda(mint: Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &["bond_multisig_meta".to_string().as_ref(), mint.as_ref()],
        &crate::ID,
    )
}

cfg_if::cfg_if! {
    if #[cfg(feature = "mainnet-beta")] {
        pub const PYTH_PROGRAM: Pubkey = pubkey!("FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH");
    } else {
        pub const PYTH_PROGRAM: Pubkey = pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s");
    }
}

cfg_if::cfg_if! {
    if #[cfg(feature = "mainnet-beta")] {
        pub const PYTH_USDC: Pubkey = pubkey!("Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD");
    } else {
        pub const PYTH_USDC: Pubkey = pubkey!("5SSkXsEKQepHHAewytPVwdej4epN1nxgLVM84L4KXgy7");
    }
}

cfg_if::cfg_if! {
    if #[cfg(feature = "mainnet-beta")] {
        pub const PROGRAM_OWNER: Pubkey = pubkey!("owNEred9E1jEEFsS2E3LRMNtAnUf6XBseqBnyKc33Pz");
    } else {
        pub const PROGRAM_OWNER: Pubkey = pubkey!("9Qx7RaqE56rHz4k1bM3Bta2dmqYGd8nLQxonde26MukW");
    }
}
