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

pub struct GuardianQuoteVerify {}

#[derive(Clone, AnchorSerialize, AnchorDeserialize, Debug)]
pub struct GuardianQuoteVerifyParams {
    pub timestamp: i64,
    pub mr_enclave: [u8; 32],
    pub idx: u32,
    pub ed25519_key: Pubkey,
    pub secp256k1_key: [u8; 64],
}

impl InstructionData for GuardianQuoteVerifyParams {}

impl Discriminator for GuardianQuoteVerifyParams {
    const DISCRIMINATOR: [u8; 8] = [168, 36, 93, 156, 157, 150, 148, 45];
}

impl Discriminator for GuardianQuoteVerify {
    const DISCRIMINATOR: [u8; 8] = [168, 36, 93, 156, 157, 150, 148, 45];
}

pub struct GuardianQuoteVerifyArgs {
    pub guardian: Pubkey,
    pub guardian_enclave_signer: Pubkey,
    pub authority: Pubkey,
    pub oracle: Pubkey,
    pub guardian_queue: Pubkey,
    pub timestamp: i64,
    pub mr_enclave: [u8; 32],
    pub idx: u32,
    pub ed25519_key: Pubkey,
    pub secp256k1_key: [u8; 64],
}
pub struct GuardianQuoteVerifyAccounts {
    pub guardian: Pubkey,
    pub enclave_signer: Pubkey,
    pub authority: Pubkey,
    pub oracle: Pubkey,
    pub guardian_queue: Pubkey,
    pub state: Pubkey,
}
impl ToAccountMetas for GuardianQuoteVerifyAccounts {
    fn to_account_metas(&self, _: Option<bool>) -> Vec<AccountMeta> {
        vec![
            AccountMeta::new(self.guardian, false),
            AccountMeta::new_readonly(self.enclave_signer, true),
            AccountMeta::new_readonly(self.authority, true),
            AccountMeta::new(self.oracle, false),
            AccountMeta::new_readonly(self.guardian_queue, false),
            AccountMeta::new_readonly(self.state, false),
        ]
    }
}

impl GuardianQuoteVerify {
    pub fn build_ix(args: GuardianQuoteVerifyArgs) -> Result<Instruction, OnDemandError> {
        Ok(crate::utils::build_ix(
            &*SWITCHBOARD_ATTESTATION_PROGRAM_ID,
            &GuardianQuoteVerifyAccounts {
                guardian: args.guardian,
                enclave_signer: args.guardian_enclave_signer,
                authority: args.authority,
                oracle: args.oracle,
                guardian_queue: args.guardian_queue,
                state: State::get_pda(),
            },
            &GuardianQuoteVerifyParams {
                timestamp: args.timestamp,
                mr_enclave: args.mr_enclave,
                idx: args.idx,
                ed25519_key: args.ed25519_key,
                secp256k1_key: args.secp256k1_key,
            },
        ))
    }
}
