use super::super::error::BtrfsError;
use crate::process::CommandResult;
use std::process::Command;

pub(crate) fn execute_command_internal(program: &str, args: &[&str]) -> Result<CommandResult, BtrfsError> {
    let output = Command::new(program).args(args).output()?;

    let stdout = String::from_utf8_lossy(&output.stdout).to_string();
    let stderr = String::from_utf8_lossy(&output.stderr).to_string();

    let exit_code = output.status.code().unwrap_or(-1);
    let success = output.status.success();

    let result = CommandResult {
        stdout,
        stderr,
        success,
        code: exit_code,
    };

    if !success {
        let stderr_msg = if result.stderr.trim().is_empty() {
            "no error message available"
        } else {
            result.stderr.trim()
        };
        return Err(BtrfsError::CommandFailed(format!(
            "Command '{}' failed with exit code {}: {}",
            program,
            exit_code,
            stderr_msg
        )));
    }

    Ok(result)
}

pub(crate) fn execute_sudo_command(program: &str, args: &[&str]) -> Result<CommandResult, BtrfsError> {
    let mut sudo_args = vec![program];
    sudo_args.extend(args.iter());
    execute_command_internal("sudo", &sudo_args)
}

pub(crate) fn execute_btrfs_command(args: &[&str]) -> Result<CommandResult, BtrfsError> {
    execute_command_internal("btrfs", args)
}

