use crate::{CloneJobPhase, DaemonId};
use chrono::{DateTime, Utc};
use serde::Serialize;
use serde_json::Value;
use uuid::Uuid;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CloneEventLevel {
    Info,
    Warn,
    Error,
}

impl CloneEventLevel {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Info => "info",
            Self::Warn => "warn",
            Self::Error => "error",
        }
    }

    pub fn parse(value: &str) -> Result<Self, crate::ControlPlaneError> {
        match value {
            "info" => Ok(Self::Info),
            "warn" => Ok(Self::Warn),
            "error" => Ok(Self::Error),
            _ => Err(crate::ControlPlaneError::Storage(format!(
                "unknown clone event level `{value}`"
            ))),
        }
    }
}

#[derive(Debug, Clone, Serialize)]
pub struct CloneJobEvent {
    pub event_id: Uuid,
    pub job_id: Uuid,
    pub daemon_id: Option<String>,
    pub phase: CloneJobPhase,
    pub level: CloneEventLevel,
    pub kind: String,
    pub message: String,
    pub details: Value,
    pub created_at: DateTime<Utc>,
}

impl CloneJobEvent {
    pub fn daemon_id(value: &Option<DaemonId>) -> Option<String> {
        value.as_ref().map(|value| value.as_str().to_string())
    }
}
