use serde::{Deserialize, Serialize};

use std::fmt::Debug;

use crate::database::TaskExecutionRecord;
pub mod execution;

/// This trait represents a task that can be executed by the task manager. All tasks must implement this trait.
pub trait Task: Send + Sync + Debug + 'static {
    fn execute(&self) -> TaskResultData;
}

/// This struct represents a task result. This is what the task returns when it is finished executing.
#[derive(Serialize, Deserialize, Debug)]
pub struct TaskResultData {
    pub result_status: TaskStatus,
    pub result_data: Option<String>,
}

/// This struct represents a task status. This is within the TaskResultData struct.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum TaskStatus {
    Initialized,
    Error,
    Cancelled,
    ReadyForDispatch,
    Dispatched,
    Running,
    Passed,
    Failed,
    Killed,
    Incomplete,
    Blocked,
}

/// This struct represents a task request. This is what the dispatcher sends to the worker.
#[derive(Debug)]
pub struct TaskRequest {
    pub request_id: String,
    pub execution_id: String,
    pub task: Box<dyn Task>,
}

/// Representation of an enqueued task execution. This is what the consumers receive from the message queue.
#[derive(Debug, Serialize, Deserialize)]
pub struct TaskExecutionEnqueued {
    // Topic to send the task execution to 
    pub topic: String,

    // Task execution record
    pub record: TaskExecutionRecord,

    // Serialized task data from the parent task request
    pub task_data: String,
}
