#![allow(deprecated)]

use_prelude!();

use super::DittoCounter;

/// Use [`doc.get_mut::<DittoMutableCounter>("...")`] to obtain a mutable CRDT counter.
///
/// A mutable CRDT counter that can be incremented while updating a document.
///
/// [`doc.get_mut::<DittoMutableCounter>("...")`]: crate::store::query_builder::DittoMutDocument::get_mut
#[deprecated(
    since = "4.14.4",
    note = "Will be removed in SDK 5.0. Use DQL queries instead"
)]
pub struct DittoMutableCounter<'doc> {
    document: &'doc mut ffi_sdk::Document,
    path: char_p::Box,
    counter: DittoCounter,
}

impl<'doc> DittoMutableCounter<'doc> {
    #[doc(hidden)]
    #[deprecated(
        note = r#"Use `.update(|doc| doc.get_mut::<DittoMutableCounter>("..."))` instead"#
    )]
    pub fn new(value: f64, document: &'doc 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<'doc> MutableValue<'doc> for DittoMutableCounter<'doc> {
    type BaseType = DittoCounter;
    fn mutable_version(
        base: Self::BaseType,
        document: &'doc 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
        ffi_sdk::ditto_document_increment_counter(self.document, self.path.as_ref(), amount)
            .into_rust_result()?;
        self.counter.value += amount;
        Ok(())
    }
}
