use anyhow::Context;
use std::os::unix::prelude::CommandExt;
use std::process::Command;

use clap::Parser;

use nmk::consts::bin::{SUDO, TMUX};
use nmk::process::{find_all_tty_processes, ProcessInfo};
use nmk::tmux::config::{CopyMode, Key};

#[derive(Debug, Parser)]
pub struct SendKeyOrCopyMode {
    #[clap(short = 't', help = "Pseudo terminal of pane")]
    pub tty: String,
    #[clap(short = 'c', help = "Pane current command")]
    pub pane_current_command: String,
    #[clap(short = 'k', help = "Key to send by tmux")]
    pub key: Key,
    #[clap(short = 'm', help = "Copy mode", possible_values = CopyMode::possible_values())]
    pub mode: CopyMode,
    #[clap(
        help = "comma separated list of commands that should enter copy mode when key is pressed"
    )]
    pub commands: String,
}

pub fn send_key_or_copy_mode(options: SendKeyOrCopyMode) -> nmk::Result<()> {
    let SendKeyOrCopyMode {
        tty,
        pane_current_command,
        commands,
        key,
        mode,
    } = options;
    let mut pane_command = pane_current_command;
    if pane_command == SUDO {
        // find the real command
        if let Ok(processes) = find_all_tty_processes(&tty) {
            if let Some(command) = find_sudo_command(&processes) {
                pane_command.clear();
                pane_command.push_str(command);
            }
        }
    }
    let should_enter_copy_mode = commands.split(',').any(|c| c == pane_command);
    let mut cmd = Command::new(TMUX);
    if should_enter_copy_mode {
        cmd.args(mode.as_args());
    } else {
        cmd.args(["send-keys", key.into()]);
    };
    let err = cmd.exec();
    Err(err).context("failed to execute tmux for send key or enter copy mode")
}

fn find_sudo_command(processes: &[ProcessInfo]) -> Option<&str> {
    let sudo = processes.iter().find(|p| p.command.starts_with(SUDO))?;
    sudo.command.split_ascii_whitespace().nth(1)
}
