use crate::api::ApiError;
use crate::batch_messages::{ActivityBatchRequest, ActivityBatchResponse};
use crate::messages::{ActivityRequest, ActivityResponse};
use async_trait::async_trait;

#[async_trait]
pub trait DataSource: Send + Sync + 'static {
    /// Create an activity for a specific participant.
    async fn create_participant_activity(
        &self,
        request: ActivityRequest,
    ) -> Result<Option<ActivityResponse>, ApiError>;

    /// BATCH: Create an activity for a specific participant.
    async fn create_participant_activity_batch(
        &self,
        request: ActivityBatchRequest,
    ) -> Result<Option<ActivityBatchResponse>, ApiError>;

    /// Update an activity for a specific participant.
    async fn update_participant_activity(
        &self,
        request: ActivityRequest,
    ) -> Result<Option<ActivityResponse>, ApiError>;

    /// BATCH: Update an activity for a specific participant.
    async fn update_participant_activity_batch(
        &self,
        request: ActivityBatchRequest,
    ) -> Result<Option<ActivityBatchResponse>, ApiError>;

    /// Delete an activity for a specific participant.
    async fn delete_participant_activity(
        &self,
        request: ActivityRequest,
    ) -> Result<Option<ActivityResponse>, ApiError>;

    /// BATCH: Delete an activity for a specific participant.
    async fn delete_participant_activity_batch(
        &self,
        request: ActivityBatchRequest,
    ) -> Result<Option<ActivityBatchResponse>, ApiError>;

    /// Check the details of an activity for a specific participant.
    /// This should NOT return any sensitive data.
    async fn participant_activity_details(
        &self,
        request: ActivityRequest,
    ) -> Result<Option<ActivityResponse>, ApiError>;

    /// BATCH: Check the details of an activity for a specific participant.
    async fn participant_activity_details_batch(
        &self,
        request: ActivityBatchRequest,
    ) -> Result<Option<ActivityBatchResponse>, ApiError>;

    /// Check the progress of an activity for a specific participant.
    /// This should NOT return any sensitive data.
    async fn participant_activity_progress(
        &self,
        request: ActivityRequest,
    ) -> Result<Option<ActivityResponse>, ApiError>;

    /// BATCH: Check the progress of an activity for a specific participant.
    async fn participant_activity_progress_batch(
        &self,
        request: ActivityBatchRequest,
    ) -> Result<Option<ActivityBatchResponse>, ApiError>;

    /// Check the result of an activity for a specific participant.
    /// This should only return how the data can be accessed, not the data itself.
    /// Or it should return the data, but encrypted for an authorized user.
    async fn participant_activity_result(
        &self,
        request: ActivityRequest,
    ) -> Result<Option<ActivityResponse>, ApiError>;

    /// BATCH: Check the result of an activity for a specific participant.
    async fn participant_activity_result_batch(
        &self,
        request: ActivityBatchRequest,
    ) -> Result<Option<ActivityBatchResponse>, ApiError>;

    // TODO: Maybe optional implementation for batch that uses the non-batch version
}
