use crate::{EncodedValue, Uleb128};
use crate::{ReadSeek, Result, Serializable};
use std::io::Write;

/// <https://source.android.com/docs/core/runtime/dex-format#encoded-array>
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EncodedArray {
    // pub size: Uleb128,
    pub values: Vec<EncodedValue>,
}

impl EncodedArray {
    /// Return the size field
    pub fn size_field(&self) -> Uleb128 {
        Uleb128(self.values.len() as u32)
    }
}

impl Serializable for EncodedArray {
    fn serialize(&self, output: &mut dyn Write) -> Result<()> {
        self.size_field().serialize(output)?;
        for value in &self.values {
            value.serialize(output)?;
        }
        Ok(())
    }

    fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
        let Uleb128(size) = Uleb128::deserialize(input)?;
        let mut values = vec![];
        for _ in 0..size {
            values.push(EncodedValue::deserialize(input)?);
        }
        Ok(Self {
            // size: Uleb128(size),
            values,
        })
    }

    fn size(&self) -> usize {
        self.size_field().size() + self.values.iter().map(|val| val.size()).sum::<usize>()
    }
}

// TODO: add tests
