use std::sync::Arc;
use anyhow::{Result, anyhow};
use async_trait::async_trait;
use uuid::Uuid;
use super::UseCase;
use crate::domain::entity::{FileShare, ShareStatus};
use crate::infrastructure::persistence::FileShareRepository;
#[derive(Debug, Clone)]
pub struct UpdateFileShareInput {
pub id: Uuid,
pub file_id: Option<Uuid>,
pub owner_id: Option<Uuid>,
pub token: Option<String>,
pub share_type: Option<ShareType>,
pub permission: Option<SharePermission>,
pub shared_with: Option<Vec<Uuid>>,
pub password_hash: Option<String>,
pub max_downloads: Option<i32>,
pub download_count: Option<i32>,
pub expires_at: Option<DateTime<Utc>>,
pub status: Option<ShareStatus>,
pub revoked_at: Option<DateTime<Utc>>,
pub revoked_by: Option<Uuid>,
pub message: Option<String>,
pub metadata: Option<serde_json::Value>,
}
#[derive(Debug, Clone)]
pub struct UpdateFileShareOutput {
pub file_share: FileShare,
}
pub struct UpdateFileShareUseCase {
repository: Arc<FileShareRepository>,
}
impl UpdateFileShareUseCase {
pub fn new(repository: Arc<FileShareRepository>) -> Self {
Self { repository }
}
}
#[async_trait]
impl UseCase for UpdateFileShareUseCase {
type Input = UpdateFileShareInput;
type Output = UpdateFileShareOutput;
async fn execute(&self, input: Self::Input) -> Result<Self::Output> {
let mut entity = self.repository.find_by_id(input.id).await?
.ok_or_else(|| anyhow!("FileShare not found"))?;
if let Some(val) = input.file_id {
entity.file_id = val;
}
if let Some(val) = input.owner_id {
entity.owner_id = val;
}
if let Some(val) = input.token {
entity.token = val;
}
if let Some(val) = input.share_type {
entity.share_type = val;
}
if let Some(val) = input.permission {
entity.permission = val;
}
if let Some(val) = input.shared_with {
entity.shared_with = val;
}
if input.password_hash.is_some() {
entity.password_hash = input.password_hash;
}
if input.max_downloads.is_some() {
entity.max_downloads = input.max_downloads;
}
if let Some(val) = input.download_count {
entity.download_count = val;
}
if input.expires_at.is_some() {
entity.expires_at = input.expires_at;
}
if let Some(val) = input.status {
entity.status = val;
}
if input.revoked_at.is_some() {
entity.revoked_at = input.revoked_at;
}
if input.revoked_by.is_some() {
entity.revoked_by = input.revoked_by;
}
if input.message.is_some() {
entity.message = input.message;
}
if let Some(val) = input.metadata {
entity.metadata = val;
}
let updated = self.repository.update(entity).await?;
Ok(UpdateFileShareOutput { file_share: updated })
}
}