use rnex_core::rmc::structures::{Result, RmcSerialize};
use std::io::{Cursor, Read, Write};
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};

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

impl RmcSerialize for Any {
    fn serialize(&self, writer: &mut impl Write) -> Result<()> {
        self.name.serialize(writer)?;

        let u32_len = self.data.len() as u32;
        (u32_len + 4).serialize(writer)?;
        self.data.serialize(writer)?;

        Ok(())
    }
    fn deserialize(reader: &mut impl Read) -> Result<Self> {
        let name = String::deserialize(reader)?;

        // also length ?
        let _len2: u32 = reader.read_struct(IS_BIG_ENDIAN)?;
        let data = Vec::deserialize(reader)?;

        Ok(Any { name, data })
    }
}

impl Any {
    pub fn try_get<T: RmcSerialize>(&self) -> Option<Result<T>> {
        if self.name != T::name() {
            return None;
        }
        return Some(T::deserialize(&mut Cursor::new(&self.data[..])));
    }
    pub fn new<T: RmcSerialize>(val: &T) -> Result<Self> {
        return Ok(Self {
            name: T::name().to_owned(),
            data: val.to_data()?,
        });
    }
}
