<?php
// download_rustdesk.php
// Place ce fichier sur ton serveur. Appelle-le depuis un <a href="download_rustdesk.php">Télécharger</a>

// CONFIG
$owner = 'rustdesk';
$repo  = 'rustdesk';
$use_cache = true;                  // true: télécharge une fois et sert depuis le disque (économie de bande)
$cache_dir = __DIR__ . '/cache';    // dossier de cache (doit être écrivable)
$github_token = getenv('GITHUB_TOKEN') ?: ''; // optionnel: augmente les limites de l'API

// ------------- Fonctions utilitaires -------------
function detect_os_from_user_agent($ua) {
    $ua = strtolower($ua);
    if (strpos($ua, 'windows') !== false) return 'windows';
    if (strpos($ua, 'mac os x') !== false || strpos($ua, 'macintosh') !== false) return 'macos';
    if (strpos($ua, 'android') !== false) return 'android';
    if (strpos($ua, 'iphone') !== false || strpos($ua, 'ipad') !== false || strpos($ua, 'ios') !== false) return 'ios';
    // heuristiques linux
    if (strpos($ua, 'linux') !== false || strpos($ua, 'x11') !== false) return 'linux';
    return 'unknown';
}

function http_get_json($url, $token = '') {
    $opts = [
        "http" => [
            "method" => "GET",
            "header" => "User-Agent: php-rustdesk-downloader/1.0\r\n" .
                        ($token ? "Authorization: token $token\r\n" : "")
        ]
    ];
    $context = stream_context_create($opts);
    $json = @file_get_contents($url, false, $context);
    if ($json === false) return null;
    return json_decode($json, true);
}

function choose_asset_for_os($assets, $os) {
    // Ordre de préférence: pattern spécifique d'abord
    $patterns = [
        'windows' => ['/x86_64.*exe$/i', '/win.*exe$/i', '/msi$/i'],
        'macos'   => ['/mac.*zip$/i','/mac.*dmg$/i','/darwin.*dmg$/i','/mac.*pkg$/i'],
        'linux'   => ['/appimage/i', '/x86_64.*AppImage/i', '/amd64.*deb$/i', '/deb$/i', '/rpm$/i', '/linux.*tar.gz/i'],
        'android' => ['/apk$/i', '/android.*apk/i'],
        'ios'     => ['/ipa$/i'],
        'unknown' => [] // fallback
    ];
    // 1) essayer pattern pour l'OS
    if (isset($patterns[$os])) {
        foreach ($patterns[$os] as $pat) {
            foreach ($assets as $a) {
                if (isset($a['name']) && preg_match($pat, $a['name'])) return $a;
            }
        }
    }
    // 2) heuristique: préférer x86_64/exe or AppImage etc.
    $fallback_order = [
        '/x86_64.*exe$/i', '/exe$/i', '/AppImage/i', '/deb$/i', '/rpm$/i', '/apk$/i'
    ];
    foreach ($fallback_order as $pat) {
        foreach ($assets as $a) {
            if (isset($a['name']) && preg_match($pat, $a['name'])) return $a;
        }
    }
    // 3) dernier recours: le premier asset
    return $assets[0] ?? null;
}

function stream_remote_file_forward_headers($url, $token = '') {
    // On fait une requête HEAD pour récupérer Content-Type/Length si possible
    $chh = curl_init($url);
    curl_setopt($chh, CURLOPT_NOBODY, true);
    curl_setopt($chh, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($chh, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($chh, CURLOPT_HEADER, true);
    curl_setopt($chh, CURLOPT_HTTPHEADER, array_merge(['User-Agent: php-rustdesk-downloader/1.0'], $token ? ["Authorization: token $token"] : []));
    $head = curl_exec($chh);
    $info = curl_getinfo($chh);
    curl_close($chh);

    // parse headers
    if ($info && isset($info['content_type'])) header('Content-Type: ' . $info['content_type']);
    if ($info && isset($info['download_content_length']) && $info['download_content_length'] > 0) {
        header('Content-Length: ' . $info['download_content_length']);
    }

    // Stream réel
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); // stream direct
    curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024 * 8);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge(['User-Agent: php-rustdesk-downloader/1.0'], $token ? ["Authorization: token $token"] : []));
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) {
        echo $data;
        if (function_exists('ob_flush')) @ob_flush();
        if (function_exists('flush')) @flush();
        return strlen($data);
    });
    $res = curl_exec($ch);
    if ($res === false) {
        http_response_code(500);
        echo "Erreur proxy: " . curl_error($ch);
    }
    curl_close($ch);
}

// ------------- Logique principale -------------
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$os = detect_os_from_user_agent($ua);

// get latest release via GitHub API
$apiUrl = "https://api.github.com/repos/$owner/$repo/releases/latest";
$release = http_get_json($apiUrl, $github_token);
if (!$release) {
    http_response_code(500);
    echo "Impossible de récupérer la dernière release depuis l'API GitHub. Vérifie la connexion et le token.";
    exit;
}
$assets = $release['assets'] ?? [];
if (empty($assets)) {
    http_response_code(404);
    echo "Aucun asset trouvé dans la dernière release.";
    exit;
}

// choisir asset
$asset = choose_asset_for_os($assets, $os);
if (!$asset) {
    http_response_code(404);
    echo "Aucun asset compatible trouvé pour votre système ($os).";
    exit;
}

$assetName = $asset['name'];
$downloadUrl = $asset['browser_download_url'];

// Si cache activé, on télécharge une fois localement (sécurité: limiter taille et vérifier)
if ($use_cache) {
    if (!is_dir($cache_dir)) mkdir($cache_dir, 0755, true);
    $local_path = $cache_dir . '/' . basename($assetName);
    if (!file_exists($local_path)) {
        // Téléchargement en arrière-plan (bloquant ici)
        $fp = fopen($local_path . '.tmp', 'w');
        $ch = curl_init($downloadUrl);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
        curl_setopt($ch, CURLOPT_FILE, $fp);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge(['User-Agent: php-rustdesk-downloader/1.0'], $github_token ? ["Authorization: token $github_token"] : []));
        $ok = curl_exec($ch);
        if ($ok === false) {
            fclose($fp);
            unlink($local_path . '.tmp');
            http_response_code(500);
            echo "Erreur de téléchargement vers le cache: " . curl_error($ch);
            curl_close($ch);
            exit;
        }
        curl_close($ch);
        fclose($fp);
        rename($local_path . '.tmp', $local_path);
    }
    // Serve le fichier local
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename($assetName) . '"');
    header('Content-Length: ' . filesize($local_path));
    header('Cache-Control: no-cache');
    header('Pragma: no-cache');

    $fp = fopen($local_path, 'rb');
    while (!feof($fp)) {
        echo fread($fp, 8192);
        if (function_exists('ob_flush')) @ob_flush();
        if (function_exists('flush')) @flush();
    }
    fclose($fp);
    exit;
}

// Sinon, faire proxy stream direct
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="' . basename($assetName) . '"');
header('Cache-Control: no-cache');
header('Pragma: no-cache');
stream_remote_file_forward_headers($downloadUrl, $github_token);
exit;
