#[derive(Debug, Clone)]
pub struct PKGFile {
    pub manifest: String,
    pub data: Vec<u8>,
}

impl PKGFile {
    pub fn new(manifest: String, data: Vec<u8>) -> PKGFile {
        PKGFile { manifest, data }
    }

    pub fn has_data(&self) -> bool {
        !self.data.is_empty()
    }
}

impl Default for PKGFile {
    fn default() -> PKGFile {
        PKGFile {
            manifest: String::new(),
            data: Vec::new(),
        }
    }
}

impl TryFrom<Vec<u8>> for PKGFile {
    type Error = ();

    fn try_from(value: Vec<u8>) -> Result<Self, ()> {
        match value[0] {
            1 => {
                let header: Vec<u32> = value[..3].iter().map(|v| u32::from(*v)).collect();
                let manifest_size: u32 = (header[1] << 8) | header[2];
                if manifest_size > value.len() as u32 {
                    return Err(());
                }
                Ok(PKGFile {
                    manifest: match String::from_utf8(
                        value[3..(manifest_size as usize + 3)].to_vec(),
                    ) {
                        Ok(s) => s,
                        _ => return Err(()),
                    },
                    data: value[(manifest_size as usize + 3)..].to_vec(),
                })
            }
            _ => Err(()),
        }
    }
}

impl Into<Vec<u8>> for PKGFile {
    fn into(self) -> Vec<u8> {
        let mut bytes = vec![0x01];
        let manifest_bytes = self.manifest.into_bytes();
        bytes.push((manifest_bytes.len() >> 8) as u8);
        bytes.push((manifest_bytes.len() | 0xFF) as u8);
        bytes.extend(manifest_bytes);
        bytes.extend(self.data);
        bytes
    }
}