<?php
if (!defined('ABSPATH')) exit;

require_once WPKGINST_PLUGIN_DIR . 'vendor/autoload.php';

use phpseclib3\Net\SSH2;
use phpseclib3\Crypt\PublicKeyLoader;

/**
 * Exécute une commande via SSH avec phpseclib3.
 */
function wpkginst_execute_ssh_command($command) {
    $host      = get_option('wpkginst_ssh_host', 'localhost');
    $username  = get_option('wpkginst_ssh_username', 'root');
    $port      = (int)get_option('wpkginst_ssh_port', 22);
    $auth_type = get_option('wpkginst_ssh_auth_type', 'key');

    try {
        $ssh = new SSH2($host, $port);
        // On définit un timeout assez long pour les installations (5 minutes)
        $ssh->setTimeout(300);

        if ($auth_type === 'key') {
            $key_content = get_option('wpkginst_ssh_private_key', '');
            if (empty($key_content)) {
                throw new Exception(__('Clé privée SSH non configurée.', 'package-installator'));
            }

            // phpseclib3 nécessite de charger la clé via le Loader
            try {
                $private_key = PublicKeyLoader::load($key_content);
            } catch (Exception $e) {
                throw new Exception(__('Format de clé privée invalide.', 'package-installator'));
            }

            if (!$ssh->login($username, $private_key)) {
                throw new Exception(__('Échec de connexion SSH avec la clé privée.', 'package-installator'));
            }
        } else {
            $password = get_option('wpkginst_ssh_password', '');
            if (empty($password)) {
                throw new Exception(__('Mot de passe SSH non configuré.', 'package-installator'));
            }
            if (!$ssh->login($username, $password)) {
                throw new Exception(__('Échec de connexion SSH avec le mot de passe.', 'package-installator'));
            }
        }

        $output = $ssh->exec($command);
        update_option('wpkginst_ssh_last_error', '');

        return ['success' => true, 'output' => $output];

    } catch (Exception $e) {
        $message = $e->getMessage();
        update_option('wpkginst_ssh_last_error', $message);
        return ['success' => false, 'message' => $message];
    }
}

/**
 * Vérifie si un paquet est installé de manière robuste.
 */
function wpkginst_get_package_status($package) {
    // 1. On récupère DIRECTEMENT le mapping complet (détection incluse)
    $mapping = wpkginst_get_os_commands_mapping();

    // 2. Sécurité : si le mapping foire, on s'assure d'avoir une chaîne pour sprintf
    $check_command_template = isset($mapping['check']) ? $mapping['check'] : "dpkg-query -W -f='\${Status}' %s 2>&1";

    $package_safe = escapeshellarg($package);

    // 3. sprintf utilise maintenant une string garantie
    $command = sprintf($check_command_template, $package_safe);
    $result  = wpkginst_execute_ssh_command($command);

    $output = $result['success'] ? $result['output'] : '';

    // 4. Vérification de l'installation selon le témoin du mapping
    $ready_string = isset($mapping['ready']) ? $mapping['ready'] : 'install ok installed';

    if (empty($ready_string)) {
        $is_installed = $result['success'] && !empty($output) && strpos($output, 'not found') === false;
    } else {
        $is_installed = (strpos($output, $ready_string) !== false);
    }

    return [
        'success'   => $result['success'],
        'installed' => $is_installed,
        'message'   => $output ?: ($result['message'] ?? '')
    ];
}

/**
 * Teste la connexion SSH.
 */
function wpkginst_test_ssh_connection() {
    $result = wpkginst_execute_ssh_command('whoami');

    return [
        'success' => $result['success'],
        'message' => $result['success']
		    /* translators: %s: Nom de l'utilisateur système retourné par whoami */
            ? sprintf(__('Connecté en tant que : %s', 'package-installator'), trim($result['output']))
            : ($result['message'] ?? __('Erreur inconnue', 'package-installator'))
    ];
}

/**
 * Récupère les stats vitales (RAM, Disque, CPU, Distro) de manière universelle.
 */
function wpkginst_get_system_stats_data() {
    // Commande universelle : /proc/meminfo pour la RAM, /proc/loadavg pour le CPU
    $combined_cmd = "cat /etc/os-release | grep '^PRETTY_NAME=' | cut -d= -f2 | tr -d '\"'; " .
                    "echo '---'; " .
                    "awk '/MemTotal/ {t=$2} /MemAvailable/ {a=$2} END {print t \",\" (t-a) \",\" a}' /proc/meminfo; " .
                    "echo '---'; " .
                    "df -hP / | awk 'NR==2 {print $2 \",\" $3 \",\" $4 \",\" $5}'; " .
                    "echo '---'; " .
                    "cut -d' ' -f1 /proc/loadavg"; // On prend la charge sur 1 min

    $res = wpkginst_execute_ssh_command($combined_cmd);

    $stats = ['distro' => 'N/A', 'ram' => 'N/A', 'disk' => 'N/A', 'cpu' => 'N/A'];

    if ($res['success'] && !empty($res['output'])) {
        $parts = explode('---', $res['output']);

        // 1. Distro
        $stats['distro'] = isset($parts[0]) ? trim($parts[0]) : 'N/A';

        // 2. RAM (Conversion kB -> Mo)
        if (isset($parts[1])) {
            $ram_data = explode(',', trim($parts[1]));
            if (count($ram_data) === 3) {
                // On divise par 1024 pour passer de kB à Mo (arrondi)
                $total = round($ram_data[0] / 1024);
                $used  = round($ram_data[1] / 1024);
                $free  = round($ram_data[2] / 1024);
                $stats['ram'] = "$total,$used,$free";
            }
        }

        // 3. Disk
        $stats['disk'] = isset($parts[2]) ? trim($parts[2]) : 'N/A';

        // 4. CPU (Load Average)
        // Note: La charge est un indice (ex: 0.50).
        // Si tu veux un %, tu peux multiplier par 100, mais l'indice est plus précis sur Linux.
        $stats['cpu'] = isset($parts[3]) ? trim($parts[3]) : 'N/A';
    }

    return $stats;
}

/**
 * Exécute une commande en arrière-plan avec nohup.
 * Retourne le PID et le chemin du log.
 */
function wpkginst_execute_ssh_background($command, $identifier = 'task') {
    $log_file = "/tmp/wpkginst_{$identifier}.log";
    // La commande magique : nohup + redirection + background + echo PID
    $bg_command = "nohup $command > $log_file 2>&1 & echo $!";

    $result = wpkginst_execute_ssh_command($bg_command);

    if ($result['success']) {
        return [
            'success' => true,
            'pid'     => trim($result['output']),
            'log'     => $log_file
        ];
    }
    return $result;
}
