<?php
namespace NeoLibraryBeta\NeoGlobal; if (!defined("ABSPATH")) { die("neoWP direct access not allowed"); }










function _update_plugin_list_assets_cache_from_server($user_type, $cache_path) {
    
    if (!($user_type === "beta" || $user_type === "dev")) {
        if (\NeoLibraryBeta\NeoGlobal\fs_file_exists(\NeoLibraryBeta\NeoGlobal\plugin_path() . "/_global-plugin-list-and-icons/" . \NeoLibraryBeta\NeoGlobal\get_plugin_list_filename($user_type))) {
            return;
        }
    }
    try {
        
        $user_cache_timeout = (7) * 24 * 60 * 60; $cache_timeout = in_array($user_type, ["beta", "dev"]) ? (5) : $user_cache_timeout;
        $plugin_list_cache_path = $cache_path . "/" . \NeoLibraryBeta\NeoGlobal\get_plugin_list_filename($user_type);
        if (\NeoLibraryBeta\NeoGlobal\fs_file_exists($plugin_list_cache_path) && !\NeoLibraryBeta\NeoGlobal\is_cache_file_outdated($plugin_list_cache_path, $cache_timeout)) { return; }
        
        try { $old_plugin_list = \NeoLibraryBeta\NeoGlobal\fs_read_json_file($plugin_list_cache_path, missing_fallback: false); } catch (\Throwable $error) { $old_plugin_list = false; }
        $plugin_list_url = \NeoLibraryBeta\NeoGlobal\get_plugin_list_and_icons_assets_url() . "/" . \NeoLibraryBeta\NeoGlobal\get_plugin_list_filename(user_type: $user_type);
        $plugin_list_resp = \NeoLibraryBeta\NeoGlobal\curl_request($plugin_list_url, timeout: 2, suppress_error: true);
        if ($plugin_list_resp === false) { \NeoLibraryBeta\NeoGlobal\global_warn_with_module_name("_global-plugin-list-and-icons-exclude-wporg", "Could not fetch plugin list from URL: " . $plugin_list_url); return; }
        try { $plugin_list = \NeoLibraryBeta\NeoGlobal\json_decode_better($plugin_list_resp); } catch (\Throwable $error) { return; }
        \NeoLibraryBeta\NeoGlobal\fs_write_json_file($plugin_list_cache_path, $plugin_list);
        
        if ($old_plugin_list !== $plugin_list) {
            $fetch_timeout = 5;
            $multi_handle = (function_exists("curl_multi_init") && function_exists("curl_multi_exec")) ? curl_multi_init() : false;
            $curl_finished = [];
            $icon_outputs = [];
            $icon_callbacks = [];
            $already_started_urls = [];
            
            foreach ($plugin_list as $plugin_data) {
                foreach ([[\NeoLibraryBeta\NeoGlobal\get_plugin_icon_filename($plugin_data["plugin-slug"]), $plugin_data["plugin-icon"]], [\NeoLibraryBeta\NeoGlobal\get_plugin_icon_filename_animated($plugin_data["plugin-slug"]), $plugin_data["plugin-icon-animated"]]] as [$filename, $url]) {
                    $path = \NeoLibraryBeta\NeoGlobal\plugin_path() . "/_global-plugin-list-and-icons/" . $filename;
                    if (isset($already_started_urls[$url]))    {                                          $icon_callbacks[$filename] = function () use (&$already_started_urls, &$icon_outputs, &$fetch_timeout,$url, $path) { return ($icon_outputs[$already_started_urls[$url]] ?? null) === null ? null : ["source" => "Waited for " . $already_started_urls[$url], "output" => $icon_outputs[$already_started_urls[$url]]];                                   }; continue; }
                    else if (\NeoLibraryBeta\NeoGlobal\fs_file_exists($path)) { $already_started_urls[$url] = $filename; $icon_callbacks[$filename] = function () use (&$already_started_urls, &$icon_outputs, &$fetch_timeout,$url, $path) { return                                                                        ["source" => "Plugin folder",                             "output" => \NeoLibraryBeta\NeoGlobal\fs_file_get_contents($path)];                                       }; continue; }
                    else if ($multi_handle === false)          { $already_started_urls[$url] = $filename; $icon_callbacks[$filename] = function () use (&$already_started_urls, &$icon_outputs, &$fetch_timeout,$url, $path) { return                                                                        ["source" => "Serial curl fetch",                         "output" => \NeoLibraryBeta\NeoGlobal\curl_request($url, timeout: $fetch_timeout, suppress_error: true)]; }; continue; }
                    else {                                       $already_started_urls[$url] = $filename;
                        $ch = curl_init($url);
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                        curl_setopt($ch, CURLOPT_TIMEOUT, $fetch_timeout);
                        curl_multi_add_handle($multi_handle, $ch);
                        $curl_id = spl_object_id($ch);
                        $icon_callbacks[$filename] = function () use (&$curl_finished, &$multi_handle,$ch,$curl_id) {
                            $running = null; curl_multi_exec($multi_handle, $running); while ($info = curl_multi_info_read($multi_handle)) { $curl_finished[spl_object_id($info["handle"])] = true; }
                            if (!($curl_finished[$curl_id] ?? false)) { return null; }
                            $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                            if (!($status_code >= 200 && $status_code < 300)) { return ["source" => "Parallel curl fetch", "output" => false]; }
                            $icon_svg_data = curl_multi_getcontent($ch);
                            curl_multi_remove_handle($multi_handle, $ch);
                            curl_close($ch);
                            return ["source" => "Parallel curl fetch", "output" => $icon_svg_data];
                        };
                    }
                }

                if ($multi_handle !== false) { do { curl_multi_exec($multi_handle, $running); curl_multi_select($multi_handle); } while ($running > 0); }
                
                while (true) {
                    foreach ($icon_callbacks as $filename => $icon_callback) {
                        if ($icon_callback === null) { continue; }
                        $callback_result = $icon_callback();
                        if ($callback_result !== null) {
                            $icon_outputs[$filename] = $callback_result["output"];
                            $icon_callbacks[$filename] = null;
                        }
                        usleep((10) * 1000);
                    }
                    if (count(\NeoLibraryBeta\NeoGlobal\array_filter_better($icon_callbacks, fn ($icon_callback) => $icon_callback !== null)) === 0) { break; }
                }

                if ($multi_handle !== false) { curl_multi_close($multi_handle); }
                
                foreach ($icon_outputs as $filename => $icon_svg_data) {
                    if ($icon_svg_data === false) {
                        \NeoLibraryBeta\NeoGlobal\global_warn_with_module_name("_global-plugin-list-and-icons-exclude-wporg", "Could not fetch plugin icon from URL: " . \NeoLibraryBeta\NeoGlobal\get_plugin_list_and_icons_assets_url() . "/" . $filename . ".");
                        continue;
                    }
                    \NeoLibraryBeta\NeoGlobal\fs_file_put_contents($cache_path . "/" . $filename, $icon_svg_data);
                }
            }
        }
    } finally {
        foreach (\NeoLibraryBeta\NeoGlobal\fs_glob($cache_path . "/*") ?: [] as $asset_file) { if (\NeoLibraryBeta\NeoGlobal\is_cache_file_outdated($asset_file, $user_cache_timeout * 2)) { \NeoLibraryBeta\NeoGlobal\fs_unlink($asset_file); } }
    }
}
