use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

/// Unique identifier for a task (the slug/name)
pub type TaskId = String;

/// How a task is defined
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskDefinition {
    /// Human-readable title
    pub title: String,
    /// Unique slug (used as TOML key and file directory name)
    pub name: String,
    /// The command to execute (e.g. "lspmux", "python")
    pub command: String,
    /// Arguments to the command
    #[serde(default)]
    pub args: Vec<String>,
    /// Working directory (None = runtime working dir)
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub working_directory: Option<PathBuf>,
    /// Run this task when dirigent starts
    #[serde(default)]
    pub run_at_startup: bool,
    /// Max lines to keep in memory buffer (0 = unlimited)
    #[serde(default = "default_buffer_size")]
    pub buffer_size: usize,
    /// Write output to disk (overrides buffer_size — keeps everything)
    #[serde(default = "default_persist")]
    pub persist_to_disk: bool,
    /// Rotate previous output file before starting
    #[serde(default)]
    pub rotate_previous: bool,
    /// Environment variables to set
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub env: Vec<(String, String)>,
}

fn default_buffer_size() -> usize {
    10000
}
fn default_persist() -> bool {
    true
}

/// Runtime state of a task
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum TaskStatus {
    Stopped,
    Running { pid: u32 },
    Finished { exit_code: Option<i32> },
    Failed { error: String },
}

/// Full info about a task (definition + runtime state)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskInfo {
    pub definition: TaskDefinition,
    pub status: TaskStatus,
    pub started_at: Option<DateTime<Utc>>,
    pub stopped_at: Option<DateTime<Utc>>,
}

/// Which output stream to read
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum OutputKind {
    Stdout,
    Stderr,
    Combined,
}
