use_prelude!();

/// Use [`ditto.store().collections().observe_local(...)`] to receive `CollectionsEvent`s.
///
/// A `CollectionsEvent` describes one or more changes to a Ditto [`Collection`].
///
/// Provides information about the changes that have occurred in relation to an event delivered when
/// observing the collections in a Ditto store. It contains information about the collections that
/// are known about as well as the collections that were previously known about in the previous
/// event, along with information about what collections have been inserted, deleted, updated, or
/// moved since the last event.
///
/// [`ditto.store().collections().observe_local(...)`]: crate::store::query_builder::PendingCollectionsOperation::observe_local
#[deprecated(
    since = "4.14.4",
    note = "Will be removed in SDK 5.0. Use DQL queries instead"
)]
#[derive(Debug)]
pub struct CollectionsEvent {
    /// Whether this event is the first one delivered to a particular observer.
    pub is_initial: bool,

    /// A list of known collections at the time of this event.
    pub collections: Vec<Collection>,

    /// A list of known collections at the time of the previous event.
    pub old_collections: Vec<Collection>,

    /// A list of indices into `collections` of newly-inserted collections.
    pub insertions: Box<[usize]>,

    /// A list of indices into `old_collections` of previously-known collections that have
    /// been removed.
    pub deletions: Box<[usize]>,

    /// A list of indices into `collections` of known updated collections.
    pub updates: Box<[usize]>,

    /// Pairs of indices (`from` and `to`) describing collections that were previously located
    /// in `old_collections` at the `from` index and are newly located in `collections` at the `to`
    /// index.
    pub moves: Vec<LiveQueryMove>,
}

impl CollectionsEvent {
    /// Create a new CollectionsEvent in initial state.
    // TODO(v5): Make pub(crate)
    #[doc(hidden)]
    #[deprecated(
        note = "Use `ditto.store().collections().observe_local(|event| ...)` to obtain a \
                `CollectionsEvent`"
    )]
    pub fn initial(collections: Vec<Collection>) -> Self {
        CollectionsEvent {
            is_initial: true,
            collections,
            old_collections: vec![],
            insertions: vec![].into(),
            deletions: vec![].into(),
            updates: vec![].into(),
            moves: vec![],
        }
    }

    /// Update a CollectionsEvent with provided data.
    // TODO(v5): Make pub(crate)
    #[doc(hidden)]
    #[deprecated(
        note = "Use `ditto.store().collections().observe_local(|event| ...)` to obtain a \
                `CollectionsEvent`"
    )]
    pub fn update(
        collections: Vec<Collection>,
        old_collections: Vec<Collection>,
        insertions: Box<[usize]>,
        deletions: Box<[usize]>,
        updates: Box<[usize]>,
        moves: Vec<LiveQueryMove>,
    ) -> Self {
        CollectionsEvent {
            is_initial: false,
            collections,
            old_collections,
            insertions,
            deletions,
            updates,
            moves,
        }
    }
}
