pub mod gap_types {
    pub static COMPLETE_LOCAL_NAME: u8 = 0x09;
    pub static SERVICE_DATA: u8 = 0x16;
    pub static UUID: u8 = 0x02;
    pub static FLAGS: u8 = 0x01;
}

pub mod flags {
    pub static LE_GENERAL_DISCOVERABLE: u8 = 0x01;
}

pub struct BlePayload {
    bytes: [u8; 39],
    occupied: usize,
}

impl BlePayload {
    pub fn add(&mut self, kind: u8, content: &[u8]) -> Result<(), ()> {
        self.check_can_write_num_bytes(content.len() + 2)?;

        self.bytes[self.occupied] = (content.len() + 1) as u8;
        self.bytes[self.occupied + 1] = kind;
        let write = &mut self.bytes[self.occupied + 2..(self.occupied + content.len() + 2)];
        write.clone_from_slice(content);
        self.occupied += 2 + content.len();
        Ok(())
    }

    pub fn add_flag(&mut self, flag: u8) -> Result<(), ()> {
        self.check_can_write_num_bytes(3)?;

        self.bytes[self.occupied] = 2;
        self.bytes[self.occupied + 1] = gap_types::FLAGS;
        self.bytes[self.occupied + 2] = flag;
        self.occupied += 3;
        Ok(())
    }

    pub fn add_service_payload(&mut self, uuid: [u8; 2], content: &[u8]) -> Result<(), ()> {
        self.check_can_write_num_bytes(4 + content.len())?;
        self.bytes[self.occupied] = (content.len() + 3) as u8;
        self.bytes[self.occupied + 1] = gap_types::SERVICE_DATA;
        self.bytes[self.occupied + 2] = uuid[0];
        self.bytes[self.occupied + 3] = uuid[1];

        let write = &mut self.bytes[self.occupied + 4..(self.occupied + content.len() + 4)];
        write.clone_from_slice(content);
        self.occupied += 4 + content.len();
        Ok(())
    }

    fn check_can_write_num_bytes(&self, number: usize) -> Result<(), ()> {
        if self.occupied + number <= self.bytes.len() {
            Ok(())
        } else {
            Err(())
        }
    }
}

impl Default for BlePayload {
    fn default() -> Self {
        BlePayload {
            bytes: [0; 39],
            occupied: 0,
        }
    }
}
impl AsRef<[u8]> for BlePayload {
    fn as_ref(&self) -> &[u8] {
        &self.bytes[0..self.occupied]
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_add() {
        let mut pld = BlePayload::default();
        pld.add(1, &[2]).unwrap();
        assert_eq!(pld.as_ref().len(), 3);
        assert_eq!(pld.as_ref(), &mut [2, 1, 2])
    }

    #[test]
    fn test_add_service_payload() {
        let mut pld = BlePayload::default();
        pld.add_service_payload([1, 2], &[2]).unwrap();
        assert_eq!(pld.as_ref(), &[4, 0x16, 1, 2, 2])
    }

    #[test]
    fn test_add_service_payload_two_times() {
        let mut pld = BlePayload::default();
        pld.add_service_payload([1, 2], &[2]).unwrap();
        pld.add_service_payload([1, 2], &[2, 3]).unwrap();

        assert_eq!(pld.as_ref(), &[4, 0x16, 1, 2, 2, 5, 0x16, 1, 2, 2, 3])
    }

    #[test]
    fn big_data_causes_error() {
        let mut pld = BlePayload::default();
        assert!(pld.add_service_payload([1, 2], &[0; 36]).is_err());
    }

    #[test]
    fn initial_size_is_zero() {
        let pld = BlePayload::default();
        assert_eq!(pld.as_ref().len(), 0);
    }
}
