//静态变量 用来存储SerialPort对象
use super::iris_protool::*;
use lazy_static::lazy_static;
use std::time::Duration;
use std::{
    // fmt::format,
    sync::{Arc, Mutex},
    thread::sleep,
};
struct SeriesSettings {
    pub port_name: String,
    pub band_rate: u32,
    pub port: Option<Box<dyn serialport::SerialPort>>,
    pub isopen: bool,
}

lazy_static! {
    static ref PORT_INFO: Arc<Mutex<SeriesSettings>> = Arc::new(Mutex::new(SeriesSettings {
        port_name: String::from("NON"),
        band_rate: 9600,
        port: None,
        isopen: false,
    }));
}

pub fn tryuseport() -> String {
    let mut port_info = PORT_INFO.lock().unwrap();
    if port_info.port_name == "NON" {
        return format!("Port is not set");
    }
    if port_info.isopen {
        drop(port_info);
        closeport();
        port_info= PORT_INFO.lock().unwrap();
    }



    port_info.port = match serialport::new(port_info.port_name.clone(), port_info.band_rate).open() {
        Ok(p) => Some(p),
        Err(e) => {
            eprintln!("Failed to open  Error: {}", e);
            return format!("Failed to open  Error: {}", e);
        }
    };
    port_info.isopen = true;
    println!("Port is open");
    return String::from("Port is open");
}

pub fn set_port_info(portname: &String, baudrate: u32) {
    let mut port_info = PORT_INFO.lock().unwrap();
    port_info.port_name = portname.to_string();
    port_info.band_rate = baudrate;

}

pub fn get_port_name() -> Vec<String> {
    let ports = serialport::available_ports().expect("No ports found!");
    println!("Available ports:{}", ports.len());
    let mut portnames: Vec<String> = Vec::new();
    println!("{}",portnames.len()   );
  //  portnames.push("COM5".to_string());
    for p in ports {
        portnames.push(p.port_name);
    }
    return portnames;
}

pub fn _reopenport() -> String {
    let mut port_info = PORT_INFO.lock().unwrap();
    if port_info.port_name == "NON" {
        return format!("Port is not set");
    }
    //关闭端口
    port_info.port = None;
    //重新打开端口
    port_info.port = match serialport::new(port_info.port_name.clone(), port_info.band_rate).open() {
        Ok(p) => Some(p),
        Err(e) => {
            eprintln!("Failed to open  Error: {}", e);
            return format!("Failed to open  Error: {}", e);
        }
    };

    String::from("Port is open")
}

pub fn closeport() -> String {
    let mut port_info = PORT_INFO.lock().unwrap();
    if port_info.port_name == "NON" {
        return format!("Port is not set");
    }
    //关闭端口
    port_info.port = None;
    println!("Port is closed");
    String::from("串口已关闭")
    //String::from("Port is closed")
}

pub fn sendtoprot(data: Vec<u8>) -> String {
    let mut port_info = PORT_INFO.lock().unwrap();
    if port_info.port_name == "NON" {
        return format!("Port is not set");
    }
    println!("{:?}", data.iter().map(|&byte| format!("{:02X}", byte)).collect::<Vec<String>>().join(" "));
    match &mut port_info.port {
        Some(p) => match p.write(&data) {
            Ok(_) => {
                println!("Data sent");
               
                return String::from("Data sent");
            }
            Err(e) => {
                eprintln!("Failed to write to port: {}", e);
                return format!("Failed to write to port: {}", e);
            }
        },
        None => {
            return format!("Port is not open");
        }
    }
}

pub fn clearserilport() -> String{
    let mut port_info = PORT_INFO.lock().unwrap();
    if port_info.port_name == "NON" {
        return "Port is not set".to_string();
    }
    let mut buf: Vec<u8> = vec![0; 1000];
    match &mut port_info.port {
        Some(p) => {
            p.set_timeout(Duration::from_millis(100)).unwrap();
            loop{
                let sizeread =match  p.read(&mut buf){
                    Ok(size)=>{size},
                    Err(_e)=>{return "Port is not open".to_string()}
                };
                if sizeread==0 { return "OK".to_string();  }
            }
        }
        None => {
            port_info.isopen=false;
           return "Port is not open".to_string();
        }

        }
    port_info.isopen=false;
    "OK".to_string()

}


pub fn readdatafromport(waittime: u64, commanid: u8) -> Vec<u8> {
    let mut port_info = PORT_INFO.lock().unwrap();
    if port_info.port_name == "NON" {
        return "Port is not set".as_bytes().to_vec();
    }
    let mut buf: Vec<u8> = vec![0; 1000];
    let mut bufforrentrun: Vec<u8> = vec![0];
    match &mut port_info.port {
        Some(p) => {
            p.set_timeout(Duration::from_millis(100)).unwrap();
            let mut sizereadoftotal=0;
            let mut nowtimetry=0;
            while sizereadoftotal <5 {
                let sizeread =match  p.read(&mut buf){
                    Ok(size)=>{size},
                    Err(_e)=>{0}
                };
                buf.truncate(sizeread);

                bufforrentrun.extend_from_slice(&buf);
                //输出接收到的数据
                println!("{:?}:{}", buf.iter().map(|&byte| format!("{:02X}", byte)).collect::<Vec<String>>().join(" "),sizeread);
                sizereadoftotal =iris_cut_before_header(&mut bufforrentrun);
                nowtimetry+=1;
                if nowtimetry>waittime{
                    return "long time no data retrun".as_bytes().to_vec();
                }
                sleep(Duration::from_millis(100));
            }
           
            nowtimetry=0;
           // println!("{:?}", bufforrentrun);
            iris_cut_before_header(&mut bufforrentrun);

            while match iris_protocol_unpack(&bufforrentrun, commanid) {
                Ok(buf) =>
                { 
                    return buf
                },
                Err(e) => {
                    if e == "ERROR_NOT_ENOUGH_DATA" {
                        true
                    } else {
                        println!("Error: {}", e.to_string());
                        return e.to_string().as_bytes().to_vec();
                    }
                }
            } {

                let sizeread = match p.read(&mut buf) {
                    Ok(size) => size,
                    Err(msg) => {
                        eprintln!("Failed to read from port: {}", msg);
                        0
                    }
                };
                buf.truncate(sizeread);
                bufforrentrun.extend_from_slice(&buf);
                //println!("{:?}", bufforrentrun.iter().map(|&byte| format!("{:X}", byte)).collect::<Vec<String>>().join(" "));
                nowtimetry+=1;
                if nowtimetry>waittime{
                    return "long time no data retrun".as_bytes().to_vec();
                }
            }

            return buf;
        }
        None => {
            return Vec::new();
        }
    }
}

pub fn iris_calc_crc(p_buffer: &[u8]) -> u16 {
    let poly: u16 = 0x8408;
    let mut crc: u16 = 0;

    for &byte in p_buffer {
        crc ^= u16::from(byte);
        for _ in 0..8 {
            let carry = crc & 1 != 0;
            crc >>= 1;
            if carry {
                crc ^= poly;
            }
        }
    }

    crc
}
pub fn readforport()->Vec<u8>{
    let mut port_info = PORT_INFO.lock().unwrap();
    if port_info.port_name == "NON" {
        return "Port is not set".as_bytes().to_vec();
    }
    let mut buf: Vec<u8> = vec![0; 5000];
    match &mut port_info.port {
        Some(p) => {
            p.set_timeout(Duration::from_millis(10)).unwrap();
            let sizeread =match  p.read(&mut buf){
                Ok(size)=>{size},
                Err(_e)=>{0}
            };
            buf.truncate(sizeread);
            return buf;
        }
        None => {
            return Vec::new();
        }
    }
}
#[test]
fn test() {
    tryuseport();
}
