use_prelude!();

use super::DittoCounter;

/// Represents a mutable CRDT counter that can be incremented while updating a document.
pub struct DittoMutableCounter {
    document: *mut ffi_sdk::Document,
    path: char_p::Box,
    counter: DittoCounter,
}

impl DittoMutableCounter {

    // TODO(pub_check)
    pub fn new (
        value: f64,
        document: *mut ffi_sdk::Document,
        path: String,
    ) -> Result<Self> {
        let path = char_p::Box::try_from(path).map_err(|_| ErrorKind::Internal)?;
        Ok(Self {
            counter: DittoCounter::new_with_value(value),
            document,
            path,
        })
    }
}

impl MutableValue for DittoMutableCounter {
    type BaseType = DittoCounter;
    fn mutable_version(base: Self::BaseType, document: &mut ffi_sdk::Document, path: char_p::Box)
        -> Result<Self>
    {
        Ok(Self { counter: base, document, path })
    }
}

impl DittoMutableCounter {

    /// Increment the value of the counter by the given `amount`
    pub fn increment(&mut self, amount: f64) -> Result<()> {
        // We have an existing document
        unsafe {
            ffi_sdk::ditto_document_increment_counter(
                &mut *self.document,
                self.path.as_ref(),
                amount,
            ).into_rust_result()?;
        }
        self.counter.value += amount;
        Ok(())
    }
}
