use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
use uuid::Uuid;

/// Immutable, append-only audit log entry.
/// Every command execution gets logged — no exceptions (BMad must-have).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditEntry {
    pub id: String,
    pub tenant_id: String,
    pub runbook_id: String,
    pub step_index: usize,
    pub command: String,
    pub safety_level: String,
    pub approved_by: Option<String>,
    pub approval_method: Option<String>, // "slack_button", "api", "auto" (read-only only)
    pub exit_code: Option<i32>,
    pub stdout_hash: Option<String>,     // SHA-256 of stdout (don't store raw output)
    pub stderr_hash: Option<String>,
    pub started_at: DateTime<Utc>,
    pub completed_at: Option<DateTime<Utc>>,
    pub duration_ms: Option<u64>,
    pub status: AuditStatus,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuditStatus {
    Pending,
    AwaitingApproval,
    Approved,
    Rejected,
    Executing,
    Completed,
    Failed,
    TimedOut,
}

impl AuditEntry {
    pub fn new(tenant_id: &str, runbook_id: &str, step_index: usize, command: &str, safety_level: &str) -> Self {
        Self {
            id: Uuid::new_v4().to_string(),
            tenant_id: tenant_id.to_string(),
            runbook_id: runbook_id.to_string(),
            step_index,
            command: command.to_string(),
            safety_level: safety_level.to_string(),
            approved_by: None,
            approval_method: None,
            exit_code: None,
            stdout_hash: None,
            stderr_hash: None,
            started_at: Utc::now(),
            completed_at: None,
            duration_ms: None,
            status: AuditStatus::Pending,
        }
    }
}
