use std::{
    ffi::OsString,
    num::NonZeroU64,
    path::Path,
    process::{Command, Stdio},
};

use anyhow::Result;
use log::debug;

use crate::platform::{Process, nvim_sockets};

pub fn instances() -> Result<impl Iterator<Item = Neovim>> {
    Ok(nvim_sockets()?.map(|(process, socket)| Neovim { process, socket }))
}

pub struct Neovim {
    pub process: Process,
    socket: OsString,
}

impl Neovim {
    pub fn edit(
        &self,
        path: &Path,
        line: Option<NonZeroU64>,
        col: Option<NonZeroU64>,
    ) -> std::io::Result<()> {
        let col = col.unwrap_or(NonZeroU64::MIN);
        let cmd = match line {
            Some(line) => format!(
                "<C-\\><C-N>:n +call\\ cursor({line},{col}) {path}<CR>",
                path = path.display()
            ),
            _ => format!("<C-\\><C-N>:n {path}<CR>", path = path.display()),
        };

        debug!("Sending {cmd:?} to {}", self.socket.display());
        Command::new("nvim")
            .arg("--server")
            .arg(&self.socket)
            .arg("--remote-send")
            .arg(cmd)
            .stdout(Stdio::null())
            .spawn()?;
        debug!("Command executed successfully!");
        Ok(())
    }
}
