use anyhow::Result;
use async_trait::async_trait;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TestFrame {
    pub header: [u8; 2],
    pub cmd: u8,
    pub length: usize,
    pub payload: Vec<u8>,
    pub checksum: u8,
    pub dts_ms: u64
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TactileAFrameMetaData {
    pub header: [u8; 2],
    pub payload_len: usize,
    pub device_addr: u8,
    pub extend_code: u8,
    pub func_code: u8,
    pub start_addr: u32,
    pub except_data_len: usize,
    // pub status: u8,
    // pub payload_data: Vec<u8>,
    pub checksum: u8,
    // pub dts_ms: u64,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TactileAReqFrame {
    pub meta: TactileAFrameMetaData,
}

#[derive(Debug, Clone, PartialEq, Eq)] 
pub struct TactileARepFrame {
    pub meta: TactileAFrameMetaData,
    pub status: TactileAFrameStatusCode,
    pub payload: Vec<u8>,
    pub dts_ms: u64
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TactileAFrameStatusCode {
    Success,
    Failure
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TactileAFrame {
    Req(TactileAReqFrame),
    Rep(TactileARepFrame)
}

#[async_trait]
pub trait FrameHandler<F, T>: Send {
    async fn on_frame(&mut self, frame: &F) -> Result<Option<Vec<T>>>;
}

