use std::ffi::OsStr;
use std::path::Path;

use crate::contexts::evaluation::domain::display_config::DisplayConfig;

pub fn run(path: &Path, editor: &OsStr) -> Result<(), std::io::Error> {
    ensure_config_file(path)?;
    let status = std::process::Command::new(editor)
        .arg(path)
        .status()
        .map_err(|e| {
            std::io::Error::other(format!("failed to launch editor {}: {e}", editor.display()))
        })?;
    if !status.success() {
        return Err(std::io::Error::other(format!(
            "editor {} exited with {status}",
            editor.display()
        )));
    }
    Ok(())
}

fn ensure_config_file(path: &Path) -> Result<(), std::io::Error> {
    if path.exists() {
        return Ok(());
    }
    if let Some(parent) = path.parent() {
        std::fs::create_dir_all(parent)?;
    }
    let config = DisplayConfig::default();
    let content = toml::to_string_pretty(&config)
        .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
    std::fs::write(path, content.as_bytes())
}

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::TempDir;

    #[test]
    fn run_returns_error_when_editor_not_found() {
        let dir = TempDir::new().unwrap();
        let config_path = dir.path().join("merge-ready.toml");
        let result = run(&config_path, OsStr::new("this-editor-does-not-exist-xyz"));
        assert!(result.is_err());
        let msg = result.unwrap_err().to_string();
        assert!(msg.contains("failed to launch editor"), "got: {msg}");
    }
}
