#![allow(dead_code)]
use crate::assets::constants::CDN_JUNO_RELEASES_COLLECTION_KEY;
use crate::types::hooks::{
AssertDeleteAssetContext, AssertUploadAssetContext, OnDeleteAssetContext,
OnDeleteFilteredAssetsContext, OnDeleteManyAssetsContext, OnUploadAssetContext,
};
#[allow(unused)]
use ic_cdk_timers::set_timer;
use junobuild_collections::constants::assets::COLLECTION_ASSET_KEY;
use junobuild_collections::types::core::CollectionKey;
use junobuild_shared::types::state::UserId;
use junobuild_storage::types::store::{Asset, AssetAssertUpload};
#[allow(unused)]
use std::time::Duration;
extern "Rust" {
fn juno_on_upload_asset(context: OnUploadAssetContext);
fn juno_on_delete_asset(context: OnDeleteAssetContext);
fn juno_on_delete_many_assets(context: OnDeleteManyAssetsContext);
fn juno_on_delete_filtered_assets(context: OnDeleteFilteredAssetsContext);
fn juno_on_upload_asset_collections() -> Option<Vec<String>>;
fn juno_on_delete_asset_collections() -> Option<Vec<String>>;
fn juno_on_delete_many_assets_collections() -> Option<Vec<String>>;
fn juno_on_delete_filtered_assets_collections() -> Option<Vec<String>>;
fn juno_assert_upload_asset(context: AssertUploadAssetContext) -> Result<(), String>;
fn juno_assert_delete_asset(context: AssertDeleteAssetContext) -> Result<(), String>;
fn juno_assert_upload_asset_collections() -> Option<Vec<String>>;
fn juno_assert_delete_asset_collections() -> Option<Vec<String>>;
}
#[allow(unused_variables)]
pub fn invoke_upload_asset(caller: &UserId, asset: &Asset) {
#[cfg(feature = "on_upload_asset")]
{
if is_system_collection(&asset.key.collection) {
return;
}
let context: OnUploadAssetContext = OnUploadAssetContext {
caller: *caller,
data: asset.clone(),
};
unsafe {
let collections = juno_on_upload_asset_collections();
if should_invoke_asset_hook(collections, &context.data.key.collection) {
set_timer(Duration::ZERO, async {
juno_on_upload_asset(context);
});
}
}
}
}
#[allow(dead_code, unused_variables)]
pub fn invoke_on_delete_asset(caller: &UserId, asset: &Option<Asset>) {
#[cfg(feature = "on_delete_asset")]
{
if let Some(asset) = asset {
if is_system_collection(&asset.key.collection) {
return;
}
}
unsafe {
let collections = juno_on_delete_asset_collections();
let filtered_assets = filter_assets(&collections, std::slice::from_ref(asset));
if !filtered_assets.is_empty() {
let context: OnDeleteAssetContext = OnDeleteAssetContext {
caller: *caller,
data: asset.clone(),
};
set_timer(Duration::ZERO, async {
juno_on_delete_asset(context);
});
}
}
}
}
#[allow(dead_code, unused_variables)]
pub fn invoke_on_delete_many_assets(caller: &UserId, assets: &[Option<Asset>]) {
#[cfg(feature = "on_delete_many_assets")]
{
unsafe {
let collections = juno_on_delete_many_assets_collections();
let filtered_assets = filter_assets(&collections, assets);
if !filtered_assets.is_empty() {
let context: OnDeleteManyAssetsContext = OnDeleteManyAssetsContext {
caller: *caller,
data: filtered_assets.clone(),
};
set_timer(Duration::ZERO, async {
juno_on_delete_many_assets(context);
});
}
}
}
}
#[allow(dead_code, unused_variables)]
pub fn invoke_on_delete_filtered_assets(caller: &UserId, assets: &[Option<Asset>]) {
#[cfg(feature = "on_delete_filtered_assets")]
{
unsafe {
let collections = juno_on_delete_filtered_assets_collections();
let filtered_assets = filter_assets(&collections, assets);
if !filtered_assets.is_empty() {
let context: OnDeleteFilteredAssetsContext = OnDeleteFilteredAssetsContext {
caller: *caller,
data: filtered_assets.clone(),
};
set_timer(Duration::ZERO, async {
juno_on_delete_filtered_assets(context);
});
}
}
}
}
#[allow(unused_variables)]
pub fn invoke_assert_upload_asset(
caller: &UserId,
asset: &AssetAssertUpload,
) -> Result<(), String> {
#[cfg(feature = "assert_upload_asset")]
{
if is_system_collection(&asset.batch.key.collection) {
return Ok(());
}
let context: AssertUploadAssetContext = AssertUploadAssetContext {
caller: *caller,
data: asset.clone(),
};
unsafe {
let collections = juno_assert_upload_asset_collections();
if should_invoke_asset_hook(collections, &context.data.batch.key.collection) {
return juno_assert_upload_asset(context);
}
}
}
Ok(())
}
#[allow(dead_code, unused_variables)]
pub fn invoke_assert_delete_asset(caller: &UserId, asset: &Asset) -> Result<(), String> {
#[cfg(feature = "assert_delete_asset")]
{
if is_system_collection(&asset.key.collection) {
return Ok(());
}
let context: AssertDeleteAssetContext = AssertDeleteAssetContext {
caller: *caller,
data: asset.clone(),
};
unsafe {
let collections = juno_assert_delete_asset_collections();
if should_invoke_asset_hook(collections, &context.data.key.collection) {
return juno_assert_delete_asset(context);
}
}
}
Ok(())
}
#[allow(clippy::unnecessary_map_or)]
fn should_invoke_asset_hook(collections: Option<Vec<String>>, collection: &CollectionKey) -> bool {
is_not_system_collection(collection) && collections.map_or(true, |c| c.contains(collection))
}
#[allow(clippy::unnecessary_map_or)]
fn filter_assets(
collections: &Option<Vec<String>>,
assets: &[Option<Asset>],
) -> Vec<Option<Asset>> {
assets
.iter()
.filter(|asset| match asset {
None => false,
Some(asset) => {
is_not_system_collection(&asset.key.collection)
&& collections.as_ref().map_or(true, |cols| {
cols.contains(&asset.key.collection.to_string())
})
}
})
.cloned() .collect()
}
fn is_system_collection(collection: &CollectionKey) -> bool {
collection == COLLECTION_ASSET_KEY || collection == CDN_JUNO_RELEASES_COLLECTION_KEY
}
fn is_not_system_collection(collection: &CollectionKey) -> bool {
!is_system_collection(collection)
}