use serde::{Deserialize, Serialize};

#[deprecated(
    since = "4.14.4",
    note = "Will be removed in SDK 5.0. Use DQL queries instead"
)]
#[derive(Serialize, Deserialize, Debug)]
pub struct DittoCounterStoredFormat {
    _value: f64,
    #[serde(rename = "_ditto_internal_type_jkb12973t4b")]
    _type: u64,
}

/// Use [`doc.get::<DittoCounter>("...")`] to obtain a read-only CRDT counter.
///
/// A CRDT counter that can be upserted as part of a document
/// or assigned to a property during an update of a document.
///
/// [`doc.get::<DittoCounter>("...")`]: crate::store::query_builder::DittoDocument::get
#[deprecated(
    since = "4.14.4",
    note = "Will be removed in SDK 5.0. Use DQL queries instead"
)]
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(from = "f64", into = "DittoCounterStoredFormat")]
pub struct DittoCounter {
    pub(crate) value: f64,
}

impl From<f64> for DittoCounter {
    fn from(value: f64) -> DittoCounter {
        DittoCounter { value }
    }
}

impl From<DittoCounter> for DittoCounterStoredFormat {
    fn from(DittoCounter { value }: DittoCounter) -> DittoCounterStoredFormat {
        Self {
            _value: value,
            _type: ::ffi_sdk::DittoCrdtType::Counter as u64,
        }
    }
}

// Implemented to satisfy clippy
impl Default for DittoCounter {
    fn default() -> Self {
        Self::new()
    }
}

impl DittoCounter {
    /// Create a counter initialized with a value of `0`.
    ///
    /// This type should only be used to initialize a `DittoCounter` in a document or to get a view
    /// of the current value of a counter.
    pub fn new() -> Self {
        Self { value: 0. }
    }

    /// Create a counter initialized at *value*
    pub(super) fn new_with_value(value: f64) -> Self {
        Self { value }
    }

    /// Get the current value of the counter
    pub fn value(&self) -> f64 {
        self.value
    }
}
