use std::sync::{Arc, Mutex};
use crate::session::client_crypto_context::ClientCryptoContext;
use crate::crypto::{asym_to_sym_key, get_shared_asym_secret};
use crate::message::DNSMessage;
use crate::string::get_fattened_public_key;
use crate::string::{decode_domain_name, DomainDecodeError};
#[derive(Ord, PartialOrd, Eq, PartialEq, Debug, Copy, Clone)]
pub enum DecodeKeyResponseError {
    DomainDecode(DomainDecodeError),
    KeyDerivation
}
pub fn decode_key_response(message: &DNSMessage, client_crypto_context: Arc<Mutex<ClientCryptoContext>>) -> Result<(), DecodeKeyResponseError>
{
    if message.answer_records.len() == 2 {
        let key_answer = &message.answer_records[1];
        match decode_domain_name(key_answer.r_data.to_bytes())
        {
            Ok(domain_name) => {
                let (fattened_public_key, _) = get_fattened_public_key(&domain_name);
                let mut context = client_crypto_context.lock().unwrap();
                match get_shared_asym_secret(&context.client_private, &fattened_public_key)
                {
                    Ok(k) => {
                        context.server_public = Some(fattened_public_key);
                        context.shared_key = Some(asym_to_sym_key(&k));
                    }
                    Err(_) => {
                        return Err(DecodeKeyResponseError::KeyDerivation);
                    }
                }
            }
            Err(e) => {
                return Err(DecodeKeyResponseError::DomainDecode(e));
            }
        }
    }
    Ok(())
}