// use serialport::SerialPort;



pub fn _iris_protocol_pack(command: u8, length_of_in: u16, buffer_in: &[u8]) -> Option<Vec<u8>> {
    if length_of_in != 0 && buffer_in.is_empty() {
        return None;
    }
    let mut pack_data: Vec<u8> = vec![0u8; 5 ];
    pack_data[0] = 0x55;
    pack_data[1] = 0xAA;
    pack_data[2] = command;
    pack_data[3] = (length_of_in >> 8) as u8;
    pack_data[4] = (length_of_in & 0xFF) as u8;

    let pack_crc: Vec<u8>=buffer_in.to_vec();
    let crc = iris_calc_crc(&pack_crc);
    pack_data.extend(pack_crc);
    pack_data.push((crc >> 8) as u8);
    pack_data.push(crc as u8);
    Some(pack_data)
}

pub fn _iris_stm32_protocol_unpack(pack_data: &[u8]) -> Result<(u8, Vec<u8>), &'static str> {
    if pack_data.is_empty() {
        return Err("ERROR_INPUT");
    }
    if pack_data[0] != 0x55 || pack_data[1] != 0xAA {
        return Err("ERROR_HEADER");
    }
    //获取数据长度
    let length_of_data = (pack_data[4] as u16) + ((pack_data[3] as u16) << 8) ;
    //判断数据长度是否足够
    if length_of_data as usize > pack_data.len() - 7 {
        return Err("ERROR_NOT_ENOUGH_DATA");
    }
    //计算crc

    let crc = iris_calc_crc(&pack_data[5..(length_of_data as usize) + 5]);
    let expected_crc = (pack_data[length_of_data as usize + 6] as u16) + ((pack_data[length_of_data as usize + 5] as u16) << 8);
    if crc != expected_crc {
        return Err("ERROR_CRC");
    }

    let command = pack_data[2];
    let buffer_out = pack_data[5..(length_of_data as usize) + 5].to_vec();
    Ok((command, buffer_out))
}

pub fn iris_protocol_unpack(pack_data: &[u8], command: u8) -> Result<Vec<u8>, &'static str> {
    if pack_data.is_empty() {
        return Err("ERROR_INPUT");
    }
    if pack_data[0] != 0x55 || pack_data[1] != 0xAA {
        return Err("ERROR_HEADER");
    }
    if pack_data[2] != command {
        if command != 0xff {  return Err("ERROR_COMMAND"); }

    }
    //获取数据长度
    let length_of_data = (pack_data[4] as u16) + ((pack_data[3] as u16) << 8) ;
    //判断数据长度是否足够
    if length_of_data as usize > pack_data.len() - 7 {
        return Err("ERROR_NOT_ENOUGH_DATA");
    }
   print!("length_of_data:{}",length_of_data);

   // println!("{:?}", pack_data.iter().map(|&byte| format!("{:X}", byte)).collect::<Vec<String>>().join(" "));

    let crc = iris_calc_crc(&pack_data[5..(length_of_data as usize) + 5]);
    let expected_crc: u16 = (pack_data[length_of_data as usize + 6] as u16) + ((pack_data[length_of_data as usize + 5] as u16) << 8);

    println!("crc:{},expected_crc:{}",crc,expected_crc);
   // println!("{}：{}",pack_data[length_of_data as usize + 6],pack_data[length_of_data as usize + 5]);


    if crc != expected_crc {
        return Err("ERROR_CRC");
    }






    Ok(pack_data[2..(length_of_data as usize) + 5].to_vec())
}

pub fn iris_cut_before_header(pack_data: &mut Vec<u8>) -> usize {

    let mut i = 0;
    while i < pack_data.len() {
        if pack_data[i] == 0x55 && pack_data.get(i + 1) == Some(&0xAA) {
            break;
        }
        i += 1;
    }

    if i == pack_data.len() {
        pack_data.clear();
        return 0;
    }

    let length_of_data = pack_data.len() - i;
    pack_data.drain(0..i);
    length_of_data
}

pub fn _iris_check_data_valid(pack_data: &[u8]) -> Result<(), &'static str> {
    if pack_data.is_empty() {
        return Err("ERROR_INPUT");
    }
    if pack_data.len() < 7 {
        return Err("ERROR_NOT_ENOUGH_DATA");
    }
    if pack_data[0] != 0x55 || pack_data[1] != 0xAA {
        return Err("ERROR_HEADER");
    }

    let length_of_data = (pack_data[4] as u16) + ((pack_data[3] as u16) << 8);
    if length_of_data as usize > pack_data.len() - 7 {
        return Err("ERROR_NOT_ENOUGH_DATA");
    }

    let crc = iris_calc_crc(&pack_data[5..(length_of_data as usize) + 5]);
    let expected_crc = (pack_data[length_of_data as usize + 6] as u16) + ((pack_data[length_of_data as usize + 5] as u16) << 8);
   // println!("crc:{},expected_crc:{}",crc,expected_crc);
    if crc != expected_crc {
        return Err("ERROR_CRC");
    }

    Ok(())
}

pub fn iris_calc_crc(p_buffer: &[u8]) -> u16 {
  //  println!("cut_before_header");
   // println!("{:?}", p_buffer.iter().map(|&byte| format!("{:X}", byte)).collect::<Vec<String>>().join(" "));
    let poly: u16 = 0x8408;
    let mut crc: u16 = 0;

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

    crc
}

