use crate::db::internal::{unsafe_delete_doc, unsafe_get_doc, unsafe_set_doc};
use crate::rules::store::{get_non_system_rules_db, get_non_system_rules_storage, get_rule_db};
use crate::types::state::CollectionType;
use crate::user::usage::types::state::{UserUsageData, UserUsageKey};
use crate::SetDoc;
use junobuild_collections::constants::db::COLLECTION_USER_USAGE_KEY;
use junobuild_collections::msg::msg_db_collection_not_found;
use junobuild_collections::types::core::CollectionKey;
use junobuild_collections::types::rules::Rule;
use junobuild_shared::ic::api::id;
use junobuild_shared::types::state::UserId;
use junobuild_utils::{decode_doc_data, encode_doc_data};
pub fn increment_usage(
collection_key: &CollectionKey,
collection_type: &CollectionType,
user_id: &UserId,
) -> Result<UserUsageData, String> {
let user_usage_key = UserUsageKey::create(user_id, collection_key, collection_type).to_key();
let user_usage_collection = COLLECTION_USER_USAGE_KEY.to_string();
let rule = get_rule_db(&user_usage_collection)
.ok_or_else(|| msg_db_collection_not_found(&user_usage_collection))?;
let doc = unsafe_get_doc(&user_usage_collection.to_string(), &user_usage_key, &rule)?;
let current_usage = doc
.as_ref()
.map(|doc| decode_doc_data(&doc.data))
.transpose()?;
let update_usage = UserUsageData::increment(¤t_usage);
let update_doc = SetDoc {
data: encode_doc_data(&update_usage)?,
description: doc.as_ref().and_then(|d| d.description.clone()),
version: doc.as_ref().and_then(|d| d.version),
};
unsafe_set_doc(
id(),
&user_usage_collection.to_string(),
&user_usage_key,
update_doc,
&rule,
)?;
Ok(update_usage)
}
pub fn delete_user_usage(user_id: &UserId) -> Result<(), String> {
let user_usage_collection = COLLECTION_USER_USAGE_KEY.to_string();
let rule = get_rule_db(&user_usage_collection)
.ok_or_else(|| msg_db_collection_not_found(&user_usage_collection))?;
delete_user_usage_for_collections(user_id, &CollectionType::Db, &user_usage_collection, &rule)?;
delete_user_usage_for_collections(
user_id,
&CollectionType::Storage,
&user_usage_collection,
&rule,
)?;
Ok(())
}
fn delete_user_usage_for_collections(
user_id: &UserId,
collection_type: &CollectionType,
user_usage_collection: &CollectionKey,
user_usage_rule: &Rule,
) -> Result<(), String> {
let rules = match collection_type {
CollectionType::Db => get_non_system_rules_db(),
CollectionType::Storage => get_non_system_rules_storage(),
};
for (collection_key, _) in rules {
let user_usage_key =
UserUsageKey::create(user_id, &collection_key, collection_type).to_key();
unsafe_delete_doc(user_usage_collection, &user_usage_key, user_usage_rule)?;
}
Ok(())
}