//! 数据接收器

use eds::crc::get_crc;
use eds::frame::*;
use fixed_queue::Vec;

/// 接收器状态
enum Status {
    Lead(u8),
    Start,
    Length1,
    Length2,
    Load,
    Crc1,
    Crc2,
    End,
    Finish,
}

/// 接收器
pub struct Reader<const N: usize> {
    lead_len: u8,
    /// 已处理的数据
    load: Vec<u8, N>,
    /// 负载总长度
    load_len: u16,
    /// 负载crc
    load_crc: u16,
    /// 接收状态
    status: Status,
}
impl<const N: usize> Reader<N> {
    /// 创建一个空的接收器
    pub const fn new(lead_len: u8) -> Self {
        Reader {
            lead_len,
            load: Vec::new(),
            load_len: 0,
            load_crc: 0,
            status: Status::Lead(0),
        }
    }
    /// 接收器是否为空
    pub fn is_empty(&self) -> bool {
        self.load.is_empty()
    }
    /// 清空接收器中处理完的数据
    fn clean(&mut self) {
        self.load.clear();
        self.status = Status::Lead(0);
    }
    /// 处理一个字节
    fn recv_one(&mut self, res: u8) -> bool {
        match self.status {
            Status::Lead(mut count) => {
                if res == CHAR_LEAD {
                    count += 1;
                    if count >= self.lead_len {
                        self.status = Status::Start;
                    } else {
                        self.status = Status::Lead(count);
                    }
                } else {
                    self.clean();
                }
            }
            Status::Start => {
                if res == CHAR_LEAD {
                } else if res == CHAR_START {
                    self.status = Status::Length1;
                } else {
                    self.clean();
                }
            }
            Status::Length1 => {
                self.load_len = (res as u16) << 8;
                self.status = Status::Length2;
            }
            Status::Length2 => {
                self.load_len |= res as u16;
                if self.load_len as usize > N {
                    self.clean();
                    self.recv_one(res);
                } else {
                    self.status = Status::Load;
                }
            }
            Status::Load => {
                let _ = self.load.push(res);
                if self.load.len() >= self.load_len as usize {
                    self.load_crc = get_crc(&self.load);
                    self.status = Status::Crc1;
                }
            }
            Status::Crc1 => {
                if res == (self.load_crc >> 8) as u8 {
                    self.status = Status::Crc2;
                } else {
                    self.clean();
                    self.recv_one(res);
                }
            }
            Status::Crc2 => {
                if res == self.load_crc as u8 {
                    self.status = Status::End;
                } else {
                    self.clean();
                    self.recv_one(res);
                }
            }
            Status::End => {
                if res == CHAR_END {
                    self.status = Status::Finish;
                    return true;
                } else {
                    self.clean();
                    self.recv_one(res);
                }
            }
            Status::Finish => {
                self.clean();
                self.recv_one(res);
            }
        }
        return false;
    }
    /// 接收数据并找出一个数据帧，返回已处理数据的字节数
    pub fn recv(&mut self, buf: &[u8]) -> usize {
        for i in 0..buf.len() {
            let res = buf[i];
            let finish = self.recv_one(res);
            if finish {
                return i + 1;
            }
        }
        return buf.len();
    }
    /// 接收到了完整数据
    pub fn is_ready(&self) -> bool {
        if let Status::Finish = self.status {
            true
        } else {
            false
        }
    }
    /// 获取接收到的数据
    pub fn get_load(&self) -> Option<&[u8]> {
        if let Status::Finish = self.status {
            Some(&self.load)
        } else {
            None
        }
    }
}
