use std::io::Read;
use std::net::TcpStream;
use openssl::ssl::SslStream;

const BUFFER_SIZE: usize = 512;
const EOL: u8 = 0x0a;

pub struct LineReader {
    /// 总字节数量
    pub buffer: Vec<u8>,
    /// 总的长度
    pub pos: usize,
}

impl LineReader {
    pub fn new() -> Self {
        LineReader { buffer: Vec::new(), pos: 0 }
    }
    fn get_eol(&self) -> Option<usize> {
        for (pos, item) in self.buffer.iter().enumerate() {
            if *item == EOL {
                return Some(pos);
            }
        }
        None
    }
    fn read_line(&mut self, stream: &mut TcpStream) -> Result<String, String> {
        loop {
            if self.get_eol().is_some() {
                break;
            }
            let mut buffer = [0u8; BUFFER_SIZE];
            let len = match stream.read(&mut buffer) {
                Ok(e) => e,
                Err(e) => {
                    return Err(format!("读取错误1001: {}", e.to_string()));
                }
            };
            self.buffer = [self.buffer.clone(), buffer[0..len].to_vec()].concat();
            self.pos += len;
        }

        if let Some(sop) = self.get_eol() {
            let line = unsafe { String::from_utf8_unchecked(self.buffer[0..sop].to_vec()) };
            // let line = String::from_utf8_lossy(&self.buffer[0..sop]).into_owned();
            let line = format!("{line}\n");
            self.pos -= sop + 1;
            self.buffer = self.buffer[sop + 1..].to_owned();
            return Ok(line.to_string());
        }
        Err("no line available".into())
    }
    fn read_ssl_line(&mut self, stream: &mut SslStream<TcpStream>) -> Result<String, String> {
        loop {
            if self.get_eol().is_some() {
                break;
            }
            let mut buffer = [0u8; BUFFER_SIZE];
            let len = match stream.read(&mut buffer) {
                Ok(e) => e,
                Err(e) => {
                    return Err(format!("读取错误1002: {}", e.to_string()));
                }
            };
            self.buffer = [self.buffer.clone(), buffer[0..len].to_vec()].concat();
            self.pos += len;
        }

        if let Some(sop) = self.get_eol() {
            let line = unsafe { String::from_utf8_unchecked(self.buffer[0..sop].to_vec()) };
            // let line = String::from_utf8_lossy(&self.buffer[0..sop]).into_owned();
            let line = format!("{line}\n");
            self.pos -= sop + 1;
            self.buffer = self.buffer[sop + 1..].to_owned();
            return Ok(line.to_string());
        }
        Err("no line available".into())
    }
    /// 读取消息头
    pub fn read(&mut self, reader: &mut TcpStream) -> Result<Vec<String>, String> {
        let mut response = vec![];
        loop {
            match self.read_line(reader) {
                Ok(e) => {
                    match e {
                        _ if e == "\r\n" => {
                            response.push(e);
                            break;
                        }
                        _ => { response.push(e); }
                    };
                }
                Err(e) => {
                    return Err(e.to_string());
                }
            }
        }
        Ok(response.clone())
    }
    /// 读取ssl消息头
    pub fn read_ssl(&mut self, reader: &mut SslStream<TcpStream>) -> Result<Vec<String>, String> {
        let mut response = vec![];

        loop {
            match self.read_ssl_line(reader) {
                Ok(e) => {
                    match e {
                        _ if e == "\r\n" => {
                            response.push(e);
                            break;
                        }
                        _ => { response.push(e); }
                    };
                }
                Err(e) => {
                    return Err(e.to_string());
                }
            }
        }
        Ok(response.clone())
    }
    /// 读取消息体
    pub fn read_body(&mut self, stream: &mut TcpStream, content_length: usize) -> Result<Vec<u8>, String> {
        loop {
            if self.pos == content_length {
                break;
            }
            let mut buffer = [0u8; BUFFER_SIZE];
            let len = match stream.read(&mut buffer) {
                Ok(e) => e,
                Err(e) => {
                    return Err(format!("读取错误1003: {}", e.to_string()));
                }
            };
            self.buffer = [self.buffer.clone(), buffer[0..len].to_vec()].concat();
            self.pos += len;
        }
        let vec_u8 = self.buffer.clone();
        self.pos -= self.buffer.len();
        self.buffer = vec![];
        return Ok(vec_u8);
    }
    /// 读取ssl消息体
    pub fn read_body_ssl(&mut self, reader: &mut SslStream<TcpStream>, content_length: usize) -> Result<Vec<u8>, String> {
        loop {
            if self.pos == content_length {
                break;
            }
            let mut buffer = [0u8; BUFFER_SIZE];
            let len = match reader.ssl_read(&mut buffer) {
                Ok(e) => e,
                Err(e) => {
                    return Err(format!("读取错误1004: {}", e.to_string()));
                }
            };
            self.buffer = [self.buffer.clone(), buffer[0..len].to_vec()].concat();
            self.pos += len;
        }
        let vec_u8 = self.buffer.clone();
        self.pos -= self.buffer.len();
        self.buffer = vec![];
        return Ok(vec_u8);
    }
}