#[derive(Clone, Copy)]
enum OpCode {
    None,
    Set,
    Add,
    Get,
}

struct Command {
    op:OpCode,
    code:u16,
    channel:u16,
    value:i32,
}

struct Endpoint {
    key:[u8;4],
    secret:[u8;12],
    mask:[u8;508],
}
impl Endpoint {
    fn parse(&self, data:&[u8]) -> Result<Vec<Command>,()>
    {
        if data.len() == 512 {
            let mut commands = Vec::new();

            let key :[u8;4] = data[0..4].try_into().unwrap_or_default();
            let secret :[u8;12] = data[4..16].try_into().unwrap_or_default();

            if key == self.key && secret == self.secret {
                let mut has_next = true;
                let mut index = 16;
                while index < 512 && has_next {
                    let data :[u8;8] = data[index..index+8].try_into().unwrap_or_default();

                    let op = match data[0] & 0x7 {
                        1 => OpCode::Get,
                        2 => OpCode::Set,
                        3 => OpCode::Add,
                        _ => OpCode::None,
                    };

                    match op {
                        OpCode::None => { has_next = false; }
                        _ => {
                            let code = (((data[1] as u16) << 8) + (data[0] as u16)) >> 3;
                            let channel = ((data[3] as u16) << 8) + (data[2] as u16);
    
                            let value = (data[7] as i32) << 24
                                + (data[6] as i32) << 16
                                + (data[5] as i32) << 8
                                + (data[4] as i32);
    
                            commands.push(Command {
                                op,
                                code,
                                channel,
                                value,
                            });
                        }
                    }

                    index += 8;
                }

                Ok(commands)
            } else {
                Err(())
            }
        } else {
            Err(())
        }
    }
}
