use std::{collections::HashMap, path::PathBuf, sync::Mutex};

pub struct LoopState {
    pub arduino_cli_path: PathBuf,
    pub features: std::collections::HashSet<crate::LoopFeature>,
    pub boards: Vec<tloop_config::Board>,
    pub firmware_sketch: Option<String>,
    pub serial_baudrate: u32,
    pub libraries: Vec<String>,
    pub env_defaults: HashMap<String, serde_json::Value>,
    pub env_vars: Mutex<HashMap<String, serde_json::Value>>,
    pub serial_stop_tx: Mutex<Option<tokio::sync::oneshot::Sender<()>>>,
}

impl LoopState {
    pub fn new(
        arduino_cli_path: PathBuf,
        features: std::collections::HashSet<crate::LoopFeature>,
        boards: Vec<tloop_config::Board>,
    ) -> Self {
        Self {
            arduino_cli_path,
            features,
            boards,
            firmware_sketch: None,
            serial_baudrate: 9600,
            libraries: Vec::new(),
            env_defaults: HashMap::new(),
            env_vars: Mutex::new(HashMap::new()),
            serial_stop_tx: Mutex::new(None),
        }
    }

    pub fn has_feature(&self, f: &crate::LoopFeature) -> bool {
        self.features.contains(f)
    }

    pub fn set_env(&self, key: String, value: serde_json::Value) {
        self.env_vars.lock().unwrap().insert(key, value);
    }

    pub fn get_env(&self, key: &str) -> Option<serde_json::Value> {
        self.env_vars.lock().unwrap().get(key).cloned()
    }

    pub fn board_fqbn(&self, name: &str) -> Option<String> {
        self.boards.iter().find(|b| b.name == name).map(|b| b.fqbn.clone())
    }
}
