use crate::prelude::*;
use solana_program::pubkey::Pubkey;
use anchor_lang::ToAccountMetas;
use anchor_lang::{AnchorDeserialize, AnchorSerialize};

pub struct OracleHeartbeat {}

#[derive(Clone, AnchorSerialize, AnchorDeserialize, Debug)]
pub struct OracleHeartbeatParams {
    pub uri: Option<[u8; 64]>,
}

impl InstructionData for OracleHeartbeatParams {}

impl Discriminator for OracleHeartbeatParams {
    const DISCRIMINATOR: [u8; 8] = [10, 175, 217, 130, 111, 35, 117, 54];
}

impl Discriminator for OracleHeartbeat {
    const DISCRIMINATOR: [u8; 8] = [10, 175, 217, 130, 111, 35, 117, 54];
}

pub struct OracleHeartbeatArgs {
    pub oracle: Pubkey,
    pub oracle_signer: Pubkey,
    pub queue: Pubkey,
    pub queue_authority: Pubkey,
    pub gc_node: Pubkey,
    pub uri: Option<[u8; 64]>,
}
pub struct OracleHeartbeatAccounts {
    pub oracle: Pubkey,
    pub oracle_signer: Pubkey,
    pub queue: Pubkey,
    pub queue_authority: Pubkey,
    pub gc_node: Pubkey,
}
impl ToAccountMetas for OracleHeartbeatAccounts {
    fn to_account_metas(&self, _: Option<bool>) -> Vec<AccountMeta> {
        vec![
            AccountMeta::new(self.oracle, false),
            AccountMeta::new_readonly(self.oracle_signer, true),
            AccountMeta::new(self.queue, false),
            AccountMeta::new_readonly(self.queue_authority, false),
            AccountMeta::new(self.gc_node, false),
        ]
    }
}

impl OracleHeartbeat {
    pub fn build_ix(args: OracleHeartbeatArgs) -> Result<Instruction, OnDemandError> {
        Ok(crate::utils::build_ix(
            &*SWITCHBOARD_ATTESTATION_PROGRAM_ID,
            &OracleHeartbeatAccounts {
                oracle: args.oracle,
                oracle_signer: args.oracle_signer,
                queue: args.queue,
                queue_authority: args.queue_authority,
                gc_node: args.gc_node,
            },
            &OracleHeartbeatParams { uri: args.uri },
        ))
    }
}
