use crate::{
    error::NaiaClientSocketError, packet_receiver::PacketReceiver, server_addr::ServerAddr,
};

use super::shared::{ERROR_QUEUE, MESSAGE_QUEUE, SERVER_ADDR};

/// Handles receiving messages from the Server through a given Client Socket
#[derive(Clone)]
pub struct PacketReceiverImpl {
    last_payload: Option<Box<[u8]>>,
}

impl PacketReceiverImpl {
    /// Create a new PacketReceiver, if supplied with the RtcDataChannel and a
    /// reference to a list of dropped messages
    pub fn new() -> Self {
        PacketReceiverImpl { last_payload: None }
    }
}

impl PacketReceiver for PacketReceiverImpl {
    fn receive(&mut self) -> Result<Option<&[u8]>, NaiaClientSocketError> {
        unsafe {
            if let Some(msg_queue) = &mut MESSAGE_QUEUE {
                if let Some(message) = msg_queue.pop_front() {
                    self.last_payload = Some(message);
                    return Ok(Some(self.last_payload.as_ref().unwrap()));
                }
            }

            if let Some(error_queue) = &mut ERROR_QUEUE {
                if let Some(error) = error_queue.pop_front() {
                    return Err(NaiaClientSocketError::Message(error));
                }
            }
        };

        Ok(None)
    }

    /// Get the Server's Socket address
    fn server_addr(&self) -> ServerAddr {
        unsafe { SERVER_ADDR }
    }
}
