use std::fmt::LowerHex;
use tokio::sync::{
    mpsc::{Receiver, Sender},
    oneshot::{Receiver as OneShotReceiver, Sender as OneShotSender},
};

pub type SerialBuffer = Vec<u8>;

pub type HeatPumpResponseSender = OneShotSender<HeatPumpResponse>;
pub type HeatPumpResponseReceiver = OneShotReceiver<HeatPumpResponse>;

pub type HeatPumpChannelContent = (HPSendingFrame, Option<HeatPumpResponseSender>);

pub type HeatPumpSender = Sender<HeatPumpChannelContent>;
pub type HeatPumpReceiver = Receiver<HeatPumpChannelContent>;

#[derive(Debug, Clone, Copy)]
pub enum HeatPumpResponse {
    Timeout,
    Success,
    Error,
}

/// FC -> Function codes used for sending data to the heat pump
#[derive(Debug, Copy, Clone)]
#[repr(u8)]
pub enum HPSendingFrame {
    First = 0x81,
    Second = 0x82,
    Third = 0x83,
}

impl LowerHex for HPSendingFrame {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:#x}", *self as u8)
    }
}

/// ABC -> Adapter board codes used for determining which data frame is being received
#[derive(Debug)]
#[repr(u8)]
pub enum HPReceivingFrame {
    First = 0x01,
    Second = 0x02,
}

impl HPReceivingFrame {
    pub fn from_u8(val: u8) -> Result<Self, ()> {
        match val {
            0x01 => Ok(HPReceivingFrame::First),
            0x02 => Ok(HPReceivingFrame::Second),
            _ => Err(()),
        }
    }
}
