<?php
/**
 * Plugin Name: VMP Security
 * Description: WordPress security plugin with malware scanner, file scanner, vulnerability scanner etc. Protect your site from threats.
 * Version: 2.2.6
 * Author: VMP Security
 * License: GPL v2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: vmpfence-security
 * Network: true
 * Requires at least: 5.0
 * Tested up to: 6.9
 * Requires PHP: 7.4
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 *
 * @package VMPFence
 * @since 1.0.0
 * @since 2.0.0 - Major Refactor with WAF, Brute Force Protection, Rate Limiting Integration
 * @since 2.1.0 - Blocked IPs, 2FA, YARA Scanner, CVE Scanner, Event Tracker, Sync Service, and other enhancements
 * @since 2.1.1 - Comprehensive overhaul with critical fixes and performance improvements
 * @since 2.1.2 - Critical fixes for scan status persistence, auto-refresh, debug log handling, and firewall layout
 * @since 2.2.0 - Added diagnostic special functions, Country Blocking, Custom Pattern Matching systems and Top Countries AJAX handler
 * @since 2.2.1 - Renamed plugin to VMP Security, text-domain updates, and minor fixes
 * @since 2.2.2 - Updated plugin name in all of the view pages, auto update option added to all options page, and dynamic update intervals for audit log and dashboard live updates, data retention choice on deactivation option added, dashboard widget added, blocked ips - waf rules - malware signatures auto sync after activation, .htaccess modification - removal and activation notice handler.
 * @since 2.2.3 - meta data cleanup on deactivation added, clear schedule crons on uninstall added, API key local check before making API calls
 * @since 2.2.4 - Added WAF Optimizer module with optimization and removal wizards, enhanced logging and error handling for WAF optimizer, and .htaccess backup/download feature, periodic license status check, onboarding, Activation modals updated
 * @since 2.2.5 - All Options page UI finished with functionality, Update Notice Added for new version, and enhanced audit log integration for all critical actions across the plugin
 * @since 2.2.6 - Updated Email alert funtionality, Audit log enhanced, scan result curation.
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

// Define plugin constants
define('VMPFENCE_VERSION', '2.2.6');
define('VMPFENCE_PLUGIN_FILE', __FILE__);
define('VMPFENCE_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('VMPFENCE_PLUGIN_URL', plugin_dir_url(__FILE__));
define('VMPFENCE_PLUGIN_BASENAME', plugin_basename(__FILE__));
define('VMPFENCE_DB_VERSION', '2.3.0');
define('VMPFENCE_MIN_WP_VERSION', '5.0');
define('VMPFENCE_MIN_PHP_VERSION', '7.4');

// Include the constants file
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-constants.php';

// Include core library files
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-config.php';
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-utils.php';
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-database.php';
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-audit-log.php';

// Audit Log Observer Architecture
require_once VMPFENCE_PLUGIN_DIR . 'includes/audit-log/class-audit-log-observer.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/audit-log/class-audit-log-observer-registry.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/audit-log/class-observer-user.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/audit-log/class-observer-content.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/audit-log/class-observer-site.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/audit-log/class-observer-vmpfence.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/audit-log/class-observer-multisite.php';

// Include API infrastructure (for license validation and premium features)
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-secure-logger.php';
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-secure-http-client.php';
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-endpoint-config.php';
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-endpoint-mapper.php';
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-api-client.php';
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-license.php';

// Include HTAccess Manager (for safe .htaccess modifications)
require_once VMPFENCE_PLUGIN_DIR . 'includes/class-htaccess-manager.php';

// Include event tracking and sync services (API-dependent features)
// CRITICAL: Load in dependency order
if (file_exists(VMPFENCE_PLUGIN_DIR . 'lib/class-logging-service.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'lib/class-logging-service.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-database.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-database.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-sync-service.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-sync-service.php';
}

// Include SIEM Installation Manager (DB v2.3.0 - Server-authoritative UUID)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-installation.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-installation.php';
}

// Include SIEM DB Upgrade (DB v2.3.0 - Adds synced columns)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-db-upgrade.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-db-upgrade.php';
}

// Include SIEM Sync Manager (DB v2.3.0 - Orchestrates data sync to backend)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-sync-manager.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-sync-manager.php';
}

// Include SIEM Base Sync module (DB v2.3.0)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/sync/class-base-sync.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/sync/class-base-sync.php';
}

// Include SIEM Scan Sync — push scan progress + results to server (DB v2.3.0)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-scan-sync.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-scan-sync.php';
}

// Include SIEM Settings Sync — push settings snapshot to server (DB v2.3.0)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/sync/class-vmpfence-sync-settings.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/sync/class-vmpfence-sync-settings.php';
}

// Include SIEM Command Executor — poll + execute commands from portal (DB v2.3.0)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-command-executor.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-vmpfence-command-executor.php';
}

// Include CVE Scanner System (API-dependent premium feature)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/cve/class-cve-sync.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/cve/class-cve-sync.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/cve/class-cve-scanner.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/cve/class-cve-scanner.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/cve/class-cve-scheduler.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/cve/class-cve-scheduler.php';
}

// Include Email Notification Service (Phase 1: Server-rendered branded emails with wp_mail fallback)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-email-service.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-email-service.php';
}

// Include Email Alert Hooks (Phase 3: WordPress hook listeners for 14 alert types)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-email-alert-hooks.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-email-alert-hooks.php';
    VMPFence_Email_Alert_Hooks::init();
}

// Include 2FA Login Handler (API-dependent feature, available for all users)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-login-2fa-handler.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-login-2fa-handler.php';
}

// Include Login Security Features (Phase 1: Last Login Column, Delete on Deactivation)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-login-security-features.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-login-security-features.php';
}

// Include 2FA Enforcement (Phase 3: Role-based 2FA requirements, Grace Period, Remember Device)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-2fa-enforcement.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-2fa-enforcement.php';
}

// Include XML-RPC Security (Phase 4: XML-RPC 2FA requirement and authentication control)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-xmlrpc-security.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-xmlrpc-security.php';
}

// Include WooCommerce Integration (Phase 5: WooCommerce 2FA and reCAPTCHA support)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-woocommerce-integration.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-woocommerce-integration.php';
}

// Include 2FA Shortcode Handler (Phase 5: Frontend 2FA management via shortcode)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-2fa-shortcode.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-2fa-shortcode.php';
}

// Include reCAPTCHA Integration (Phase 6: Google reCAPTCHA v3 for login/registration)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-recaptcha-integration.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-recaptcha-integration.php';
}

// Phase 7: IP Allowlist helper class (for Login Security IP bypass)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-ip-allowlist.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-ip-allowlist.php';
}

// Include Trusted Hashes DB (for YARA Scanner integrity checks)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-trusted-hashes-db.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-trusted-hashes-db.php';
}

// Include WP Integrity Checker (for YARA Scanner)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-wp-integrity-checker.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-wp-integrity-checker.php';
}

// Include firewall exceptions
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-firewall-exception.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-firewall-exception.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-allow-exception.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-allow-exception.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-block-exception.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-block-exception.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-block-xss-exception.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-block-xss-exception.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-block-sqli-exception.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-block-sqli-exception.php';
}

// Include firewall bootstrap
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/models/class-firewall-config.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-firewall-config.php';
}

// Include WAF integration
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/init-waf.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/init-waf.php';
}

// Include Signature Sync AJAX handler (for scanner signature sync)
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/signature-sync-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/signature-sync-ajax.php';
}

// Include Disable Debug AJAX handler (for server state scanner)
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/disable-debug-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/disable-debug-ajax.php';
}

// Load Blocked IP model (must load early for admin pages)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/models/class-blocked-ip.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-blocked-ip.php';
}

// Include blocked IP sync class (required for AJAX handler)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-blocked-ip-sync.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-blocked-ip-sync.php';
}

// Include blocked IP scheduler (manages automatic hourly sync cron)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-blocked-ip-scheduler.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-blocked-ip-scheduler.php';
}

// Include malware signature sync class
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-signature-sync.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-signature-sync.php';
}

// Include diagnostic special functions controller
if (file_exists(VMPFENCE_PLUGIN_DIR . 'tools/controllers/class-diagnostic-special-functions.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'tools/controllers/class-diagnostic-special-functions.php';
}

// Include malware signature scheduler (manages automatic hourly sync cron)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-signature-scheduler.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-signature-scheduler.php';
}

// Include WAF rule class (required for WAF scheduler)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/models/class-waf-rule.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-waf-rule.php';
}

// Include WAF rule scheduler (manages automatic hourly sync cron for premium)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-waf-rule-scheduler.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-waf-rule-scheduler.php';
}

// Include Blocked IP Sync AJAX handler (for IP sync)
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/blocked-ip-sync-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/blocked-ip-sync-ajax.php';
}

// Include Blocked IP Search AJAX handler
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/search-blocked-ips-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/search-blocked-ips-ajax.php';
}

// Include Unblock IP AJAX handler
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/unblock-ip-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/unblock-ip-ajax.php';
}

// Include Activation Notices Handler (WAF sync toast notifications)
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/includes/activation-notices.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/includes/activation-notices.php';
}

// Include Activation Modal (shows license form on plugin pages after activation)
if (is_admin()) {
    add_action('admin_footer', function() {
        include_once VMPFENCE_PLUGIN_DIR . 'admin/views/activation-modal.php';
    });
}

// Include All Options AJAX handler
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'all-options/ajax-handler.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'all-options/ajax-handler.php';
}

// Include Dashboard Widget
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-dashboard-widget.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-dashboard-widget.php';
}

// ============================================
// COUNTRY BLOCKING SYSTEM
// ============================================

// Include GeoIP Lookup (Local Database)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-geoip-lookup.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-geoip-lookup.php';
}

// Include WordPress Version Hider
if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-wp-version-hider.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-wp-version-hider.php';
    // Initialize version hiding hooks
    VMPFence_WP_Version_Hider::init();
}

// Include Country Blocking Model
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/models/class-blocked-country.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-blocked-country.php';
}

// Include Country Blocker Controller (called by firewall bootstrap)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-country-blocker.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-country-blocker.php';
}

// Include Country Blocking AJAX Handlers (admin only)
if (is_admin()) {
    if (file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/block-country-ajax.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/block-country-ajax.php';
    }
    if (file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/unblock-country-ajax.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/unblock-country-ajax.php';
    }
    if (file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/get-blocked-countries-ajax.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/get-blocked-countries-ajax.php';
    }
    // Include Custom Pattern AJAX handler
    if (file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/custom-pattern-ajax.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/custom-pattern-ajax.php';
    }
    
    // Include activation toast notification handler
    if (file_exists(VMPFENCE_PLUGIN_DIR . 'admin/includes/activation-notices.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'admin/includes/activation-notices.php';
    }
}

// Include Login Security AJAX handler (for 2FA management)
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/login-security-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/login-security-ajax.php';
}

// Include Audit Log AJAX handler
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/audit-log-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/audit-log-ajax.php';
}

// Include YARA Scanner AJAX handler (for YARA deep scanning)
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/yara-scanner-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/yara-scanner-ajax.php';
}

// Include Brute Force Protection integration
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/init-brute-force.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/init-brute-force.php';
}

// Include Rate Limiting integration  
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/init-rate-limit.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/init-rate-limit.php';
}

// Load rate limiting models early (before bootstrap)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/models/class-rate-limiter.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-rate-limiter.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/models/class-visitor-classifier.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-visitor-classifier.php';
}

// Load allowlist models and controllers
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/models/class-param-allowlist.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-param-allowlist.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-allowlist-controller.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-allowlist-controller.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-rate-limit-controller.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-rate-limit-controller.php';
}

// Load IP whitelist functionality (must load before bootstrap)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/models/class-ip-range.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-ip-range.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-ip-whitelist-controller.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-ip-whitelist-controller.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-service-allowlist-controller.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-service-allowlist-controller.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-banned-url-controller.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-banned-url-controller.php';
}

// Include Pattern Matcher Classes (BEFORE bootstrap)
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-pattern-block-exception.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/exceptions/class-pattern-block-exception.php';
}
if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-pattern-matcher.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/controllers/class-pattern-matcher.php';
}

if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/class-bootstrap.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/class-bootstrap.php';
    // Initialize firewall on plugins_loaded hook so WordPress constants/functions are available
    add_action('plugins_loaded', function() {
        // Only initialize firewall if tables exist (after activation)
        global $wpdb;
        $config_table = $wpdb->prefix . 'vmpfence_config';
        if ($wpdb->get_var("SHOW TABLES LIKE '{$config_table}'") === $config_table) {
            $bootstrap = new VMPFence_Firewall_Bootstrap();
            $bootstrap->init();
        }
    }, 1); // Priority 1 to run early but after WordPress loads
}

// Include the main plugin class
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-security-core.php';

// Include scanner classes
require_once VMPFENCE_PLUGIN_DIR . 'includes/class-file-scanner.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/class-ajax-handler.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/class-user-monitor.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/class-file-repair-engine.php';
require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-percentage.php';

// Include new scan options configuration
require_once VMPFENCE_PLUGIN_DIR . 'lib/class-vmpfence-scan-config.php';

// Include scan options AJAX handler
require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/scan-options-ajax.php';

// Include firewall options AJAX handler
require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/firewall-options-ajax.php';

// Include top IPs AJAX handler
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/top-ips-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/top-ips-ajax.php';
}

// Include top countries AJAX handler
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/top-countries-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/top-countries-ajax.php';
}

// Include status modal system
if (file_exists(VMPFENCE_PLUGIN_DIR . 'status-modal/class-bootstrap.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'status-modal/class-bootstrap.php';
    VMPFence_Status_Modal_Bootstrap::init();
}

// Include allowlist AJAX handler
require_once VMPFENCE_PLUGIN_DIR . 'firewall/ajax/class-allowlist-ajax.php';

// Include scan percentage AJAX handler
require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/scan-percentage-ajax.php';

// Include custom pattern AJAX handler (Day 55)
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'admin/ajax/custom-pattern-ajax.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/ajax/custom-pattern-ajax.php';
}

// Include tools module bootstrap
if (file_exists(VMPFENCE_PLUGIN_DIR . 'tools/class-bootstrap.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'tools/class-bootstrap.php';
}

// Include setup wizard (for first-time setup)
if (is_admin()) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/setup-wizard.php';
    VMPFence_Setup_Wizard::init();
}

// Include dashboard (main admin interface)
if (is_admin()) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/dashboard.php';
    // Dashboard class auto-initializes via constructor
}

// Include onboarding system (guided tours for first-time users)
if (is_admin()) {
    require_once VMPFENCE_PLUGIN_DIR . 'admin/includes/class-onboarding.php';
    VMPFence_Onboarding::init();
}

// Include deactivation feedback
if (is_admin() && file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-deactivation-feedback.php')) {
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-deactivation-feedback.php';
}

// Register scan monitoring hooks
add_action('init', function() {
    if (class_exists('VMPFence_Scan_Monitor')) {
        VMPFence_Scan_Monitor::registerActions();
    }
});

// Initialize allowlist AJAX handlers
add_action('init', function() {
    if (class_exists('VMPFence_Allowlist_Ajax')) {
        VMPFence_Allowlist_Ajax::init();
    }
});

/**
 * Check database version and run migrations if needed
 *
 * @since 2.0.0
 * @return void
 */
function vmpfence_check_db_version() {
    $current_db_version = get_option('vmpfence_db_version', '0.0.0');
    
    // If database version is older than current, run migrations
    if (version_compare($current_db_version, VMPFENCE_DB_VERSION, '<')) {
        require_once VMPFENCE_PLUGIN_DIR . 'lib/class-database.php';
        
        // Run migrations for existing tables
        VMPFence_Database::run_migrations($current_db_version);
        
        // Create new tables that don't exist (like vmpfence_waf_rules)
        VMPFence_Database::create_tables();
        
        // Update database version
        update_option('vmpfence_db_version', VMPFENCE_DB_VERSION);
    }
}
add_action('plugins_loaded', 'vmpfence_check_db_version', 5);

/**
 * Initialize event tracking system (API-dependent premium feature)
 *
 * @since 2.0.0
 * @since 2.2.2 - Added data retention choice on deactivation check
 * @return void
 */
function vmpfence_init_event_tracking() {
    // Check data retention choice on deactivation
    $enable_deactivation_choice = get_option('vmpfence_enable_deactivation_choice', 0);
    if ($enable_deactivation_choice) {
        $data_action = get_transient('vmpfence_deactivation_data_action');
        if ($data_action === 'delete') {
            return;
        }
    }

    // Create event logging tables (always needed for local logging)
    if (class_exists('VMPFence_Logging_Database')) {
        $logging_db = new VMPFence_Logging_Database();
        $logging_db->install();
    }
    
    // Only initialize tracker and sync if API is available (premium feature)
    if (!VMPFence_Config::is_api_available()) {
        return;
    }
    
    // Initialize sync service for background event syncing
    if (class_exists('VMPFence_Sync_Service')) {
        $sync_service = VMPFence_Sync_Service::get_instance();
        // Note: vmpfence_daily_sync cron is scheduled in vmpfence_activate() with staggered timing
    }
}
add_action('plugins_loaded', 'vmpfence_init_event_tracking', 10);

/**
 * Initialize Audit Log Observer Registry
 *
 * Loads observer classes based on the current logging mode.
 * Priority 15 ensures all VMPFence core classes are loaded first.
 *
 * @since 2.2.5
 * @return void
 */
function vmpfence_init_audit_log_observers() {
    if (get_option('vmpfence_enable_audit_log', true)) {
        VMPFence_Audit_Log_Observer_Registry::init();
    }
}
add_action('plugins_loaded', 'vmpfence_init_audit_log_observers', 15);

/**
 * Handle daily event sync to API
 *
 * @since 2.0.0
 * @return void
 */
function vmpfence_handle_daily_sync() {
    // Only run if API is available
    if (!VMPFence_Config::is_api_available()) {
        return;
    }
    
    if (class_exists('VMPFence_Sync_Service')) {
        $sync_service = VMPFence_Sync_Service::get_instance();
        $sync_service->perform_daily_sync();
    }
}
add_action('vmpfence_daily_sync', 'vmpfence_handle_daily_sync');

/**
 * Initialize CVE Scanner scheduler
 *
 * @since 2.0.0
 * @return void
 */
function vmpfence_init_cve_scheduler() {
    // Only initialize if API is available and class exists
    if (VMPFence_Config::is_api_available() && class_exists('VMPFence_CVE_Scheduler')) {
        VMPFence_CVE_Scheduler::init();
    }
}
add_action('plugins_loaded', 'vmpfence_init_cve_scheduler', 15);

/**
 * Initialize Blocked IP Scheduler (for real-time IP blocklist)
 *
 * @since 2.0.0
 * @return void
 */
function vmpfence_init_blocked_ip_scheduler() {
    if (class_exists('VMPFence_Blocked_IP_Scheduler')) {
        VMPFence_Blocked_IP_Scheduler::init();
    }
}
add_action('plugins_loaded', 'vmpfence_init_blocked_ip_scheduler', 20);

/**
 * Initialize Signature Scheduler (for malware signature sync)
 *
 * @since 2.1.2
 * @return void
 */
function vmpfence_init_signature_scheduler() {
    if (class_exists('VMPFence_Signature_Scheduler')) {
        VMPFence_Signature_Scheduler::init();
    }
}
add_action('plugins_loaded', 'vmpfence_init_signature_scheduler', 20);

/**
 * Initialize WAF Rule Scheduler (for firewall rule sync - premium only)
 *
 * @since 2.1.2
 * @return void
 */
function vmpfence_init_waf_rule_scheduler() {
    if (class_exists('VMPFence_WAF_Rule_Scheduler')) {
        VMPFence_WAF_Rule_Scheduler::init();
    }
}
add_action('plugins_loaded', 'vmpfence_init_waf_rule_scheduler', 20);

/**
 * Add SIEM sync cron interval (5 minutes)
 *
 * @since 2.2.4
 */
add_filter('cron_schedules', function ($schedules) {
    if (!isset($schedules['vmpfence_5min'])) {
        $schedules['vmpfence_5min'] = array(
            'interval' => 300,
            'display'  => __('Every 5 Minutes (SIEM Sync)', 'vmpfence-security'),
        );
    }
    return $schedules;
});

/**
 * Handle SIEM sync cron
 *
 * @since 2.2.4
 */
add_action('vmpfence_siem_sync', function () {
    if (!class_exists('VMPFence_Config') || !VMPFence_Config::is_api_available()) {
        return;
    }
    if (class_exists('VmpFence_Sync_Manager')) {
        $manager = new VmpFence_Sync_Manager();
        $manager->sync_all();
    }
});

/**
 * Retry site identification (cron callback)
 *
 * @since 2.2.4
 */
add_action('vmpfence_retry_identification', function () {
    if (class_exists('VmpFence_Installation')) {
        $uuid = VmpFence_Installation::get_installation_uuid(true);
        if (!$uuid || strpos($uuid, 'temp-') === 0) {
            // Still no server UUID — schedule another retry in 5 minutes
            wp_schedule_single_event(time() + 300, 'vmpfence_retry_identification');
        }
    }
});

/**
 * Initialize Country Blocker (for country-based access control - premium only)
 *
 * @since 2.2.0
 * @return void
 */
function vmpfence_handle_geoip_update() {
    if (class_exists('VMPFence_GeoIP_Lookup')) {
        VMPFence_GeoIP_Lookup::import_database();
    }
}
add_action('vmpfence_geoip_update', 'vmpfence_handle_geoip_update');

/**
 * Main plugin initialization function
 *
 * @since 1.0.0
 * @return void
 */
function vmpfence_init() {
    // Check minimum requirements
    if (!vmpfence_check_requirements()) {
        return;
    }

    // Initialize the main plugin class
    VMPFence_Security_Core::get_instance();
}

/**
 * Check plugin requirements
 *
 * @since 1.0.0
 * @return bool
 */
function vmpfence_check_requirements() {
    global $wp_version;

    // Check WordPress version
    if (version_compare($wp_version, VMPFENCE_MIN_WP_VERSION, '<')) {
        add_action('admin_notices', 'vmpfence_wp_version_notice');
        return false;
    }

    // Check PHP version
    if (version_compare(PHP_VERSION, VMPFENCE_MIN_PHP_VERSION, '<')) {
        add_action('admin_notices', 'vmpfence_php_version_notice');
        return false;
    }

    return true;
}

/**
 * WordPress version notice
 *
 * @since 1.0.0
 * @return void
 */
function vmpfence_wp_version_notice() {
    echo '<div class="notice notice-error"><p>';
    printf(
        /* translators: %s: minimum WordPress version required */
        esc_html__('VMP Security requires WordPress %s or higher. Please update WordPress.', 'vmpfence-security'),
        esc_html( VMPFENCE_MIN_WP_VERSION )
    );
    echo '</p></div>';
}

/**
 * PHP version notice
 *
 * @since 1.0.0
 * @return void
 */
function vmpfence_php_version_notice() {
    echo '<div class="notice notice-error"><p>';
    printf(
        /* translators: %1$s: minimum PHP version required, %2$s: current PHP version */
        esc_html__('VMP Security requires PHP %1$s or higher. Your current PHP version is %2$s.', 'vmpfence-security'),
        esc_html( VMPFENCE_MIN_PHP_VERSION ),
        esc_html( PHP_VERSION )
    );
    echo '</p></div>';
}

/**
 * Setup completion notice
 *
 * @since 1.0.0
 * @return void
 */
function vmpfence_setup_complete_notice() {
    if (!get_option('vmpfence_setup_complete_notice', false)) {
        return;
    }
    
    $gsb_consent = get_option('vmpfence_gsb_consent', 'no');
    
    echo '<div class="notice notice-success is-dismissible vmpfence-setup-notice" id="vmpfence-setup-complete-notice"><p>';
    if ($gsb_consent === 'yes') {
        esc_html_e('VMP Security setup completed! Google Safe Browsing protection is now active for enhanced security.', 'vmpfence-security');
    } else {
        esc_html_e('VMP Security setup completed! Your security scans are now ready. You can enable additional features like Google Safe Browsing in the scan settings.', 'vmpfence-security');
    }
    echo ' <span class="vmpfence-countdown" style="font-weight: normal; opacity: 0.7;">' . esc_html__('(Auto-closing in 10 seconds)', 'vmpfence-security') . '</span>';
    echo '</p></div>';
    
    // Delete the notice option so it only shows once
    delete_option('vmpfence_setup_complete_notice');
}

/**
 * Enqueue scripts and styles for setup completion notice
 *
 * @since 1.0.0
 * @return void
 */
function vmpfence_setup_notice_scripts() {
    if (!get_option('vmpfence_setup_complete_notice', false)) {
        return;
    }
    
    // Enqueue jQuery
    wp_enqueue_script('jquery');
    
    // Add JavaScript for auto-dismiss timer using wp_add_inline_script
    $inline_script = "
    jQuery(document).ready(function($) {
        var \$notice = $('#vmpfence-setup-complete-notice');
        var \$countdown = $('.vmpfence-countdown');
        var timeLeft = 10;
        
        // Update countdown every second
        var countdownInterval = setInterval(function() {
            timeLeft--;
            if (timeLeft > 0) {
                \$countdown.text('" . esc_js(__('(Auto-closing in', 'vmpfence-security')) . " ' + timeLeft + ' " . esc_js(__('seconds)', 'vmpfence-security')) . ")');
            } else {
                \$countdown.text('" . esc_js(__('(Closing...)', 'vmpfence-security')) . "');
            }
        }, 1000);
        
        // Auto-dismiss after 10 seconds
        setTimeout(function() {
            clearInterval(countdownInterval);
            \$notice.fadeOut(500, function() {
                $(this).remove();
            });
        }, 10000);
        
        // Clear timer if user manually dismisses
        \$notice.on('click', '.notice-dismiss', function() {
            clearInterval(countdownInterval);
        });
    });
    ";
    wp_add_inline_script('jquery', $inline_script);
    
    // Add CSS using wp_add_inline_style
    $inline_style = "
    .vmpfence-setup-notice {
        border-left-color: #00a32a !important;
    }
    .vmpfence-countdown {
        font-size: 0.9em;
        color: #666;
    }
    ";
    wp_add_inline_style('common', $inline_style);
}

// Add setup completion notice and scripts
add_action('admin_notices', 'vmpfence_setup_complete_notice');
add_action('admin_enqueue_scripts', 'vmpfence_setup_notice_scripts');

/**
 * Update available notice
 *
 * Shows a dismissible admin notice when a newer version of VMP Security
 * is available in the WordPress update system. Checks the update_plugins
 * site transient for pending updates.
 *
 * @since 2.2.5
 * @return void
 */
function vmpfence_update_available_notice() {
    // Only show to users who can update plugins
    if (!current_user_can('update_plugins')) {
        return;
    }

    // Only show after license is activated (setup completed)
    if (get_option('vmpfence_needs_setup', false)) {
        return;
    }

    // Check if user dismissed this notice for the current available version
    $dismissed_version = get_user_meta(get_current_user_id(), 'vmpfence_dismissed_update_notice', true);

    // Check WordPress update transient for available updates
    $update_plugins = get_site_transient('update_plugins');
    if (empty($update_plugins->response) || !isset($update_plugins->response[VMPFENCE_PLUGIN_BASENAME])) {
        return;
    }

    $update_info = $update_plugins->response[VMPFENCE_PLUGIN_BASENAME];
    $new_version = isset($update_info->new_version) ? $update_info->new_version : '';

    if (empty($new_version) || version_compare(VMPFENCE_VERSION, $new_version, '>=')) {
        return;
    }

    // Don't show if user dismissed this specific version
    if ($dismissed_version === $new_version) {
        return;
    }

    $update_url = wp_nonce_url(
        self_admin_url('update.php?action=upgrade-plugin&plugin=' . urlencode(VMPFENCE_PLUGIN_BASENAME)),
        'upgrade-plugin_' . VMPFENCE_PLUGIN_BASENAME
    );
    $plugin_slug = isset($update_info->slug) ? $update_info->slug : 'vmpfence-security';
    $details_url = self_admin_url('plugin-install.php?tab=plugin-information&plugin=' . urlencode($plugin_slug) . '&section=changelog&TB_iframe=true&width=772&height=788');
    $dismiss_nonce = wp_create_nonce('vmpfence_dismiss_update_notice');

    echo '<div class="notice notice-warning is-dismissible vmpfence-update-available-notice" id="vmpfence-update-available-notice" style="margin-left:0 !important; padding: 16px; font-size: 15px; line-height: 1.6;">';
    echo '<p style="margin: 0; font-size: 15px;">';
    printf(
        /* translators: %1$s: new version number, %2$s: details link, %3$s: update link */
        wp_kses(
            __('<strong>VMP Security %1$s</strong> is available. <a href="%2$s" class="thickbox open-plugin-details-modal">View version %1$s details</a> or <a href="%3$s">update now</a>.', 'vmpfence-security'),
            array(
                'strong' => array(),
                'a'      => array('href' => array(), 'class' => array()),
            )
        ),
        esc_html($new_version),
        esc_url($details_url),
        esc_url($update_url)
    );
    echo '</p>';
    echo '</div>';

    // Inline JS to handle dismiss via AJAX
    ?>
    <script type="text/javascript">
    jQuery(document).ready(function($) {
        $(document).on('click', '#vmpfence-update-available-notice .notice-dismiss', function() {
            $.post(ajaxurl, {
                action: 'vmpfence_dismiss_update_notice',
                nonce: '<?php echo esc_js($dismiss_nonce); ?>',
                version: '<?php echo esc_js($new_version); ?>'
            });
        });
    });
    </script>
    <?php
}
add_action('admin_notices', 'vmpfence_update_available_notice');

/**
 * AJAX handler to dismiss the update available notice
 *
 * @since 2.2.5
 * @return void
 */
function vmpfence_dismiss_update_notice_ajax() {
    check_ajax_referer('vmpfence_dismiss_update_notice', 'nonce');

    if (!current_user_can('update_plugins')) {
        wp_send_json_error('Insufficient permissions');
    }

    $version = isset($_POST['version']) ? sanitize_text_field(wp_unslash($_POST['version'])) : '';
    if (!empty($version)) {
        update_user_meta(get_current_user_id(), 'vmpfence_dismissed_update_notice', $version);
    }

    wp_send_json_success();
}
add_action('wp_ajax_vmpfence_dismiss_update_notice', 'vmpfence_dismiss_update_notice_ajax');

/**
 * Enable automatic plugin updates based on user preference
 * 
 * @since 2.2.2
 * @param bool $update Whether to update
 * @param object $item Plugin update object
 * @return bool Whether to auto-update this plugin
 */
add_filter('auto_update_plugin', function($update, $item) {
    // Only handle VMP Security plugin
    if (!isset($item->slug) || $item->slug !== 'vmpfence') {
        return $update;
    }
    
    // Check user preference from All Options page
    return (bool) VMPFence_Config::get('auto_update', 0);
}, 10, 2);

// Ensure all database tables exist (comprehensive check on every admin page load)
add_action('admin_init', function() {
    // Only check once per day to avoid performance impact
    $last_check = get_option('vmpfence_last_table_check', 0);
    $current_time = time();
    
    // Check if 24 hours have passed or if this is first check
    if ($current_time - $last_check > 86400 || $last_check === 0) {
        if (class_exists('VMPFence_Database')) {
            VMPFence_Database::ensure_all_tables_exist();
            update_option('vmpfence_last_table_check', $current_time);
        }
    }
}, 1); // Priority 1 to run before other admin_init hooks

// Auto-create trusted hashes table if it doesn't exist (for YARA Scanner)
add_action('admin_init', function() {
    if (class_exists('VMPFence_Trusted_Hashes_DB') && !VMPFence_Trusted_Hashes_DB::table_exists()) {
        VMPFence_Trusted_Hashes_DB::create_table();
    }
});

// Auto-create API logging tables if they don't exist (for Event Tracker & Analytics)
add_action('admin_init', function() {
    if (class_exists('VMPFence_Logging_Database') && !VMPFence_Logging_Database::tables_exist()) {
        VMPFence_Logging_Database::ensure_tables_exist();
    }
}, 5);

// Auto-create standalone events table if missing (prevents "Unknown column 'time'" errors)
add_action('admin_init', function() {
    if (class_exists('VMPFence_Database') && !VMPFence_Database::events_table_exists()) {
        VMPFence_Database::ensure_events_table_exists();
    }
}, 5);

// Migrate blocked IPs table to add is_active and source columns
add_action('admin_init', function() {
    // Check if migration is needed (only run once)
    $migration_done = get_option('vmpfence_blocked_ips_migration_2_0_1', false);
    if (!$migration_done) {
        if (class_exists('VMPFence_Database')) {
            VMPFence_Database::migrate_blocked_ips_table();
            update_option('vmpfence_blocked_ips_migration_2_0_1', true);
        }
    }
}, 5);

// Periodic license status check (throttled to 1 hour) - ensures license key is current
add_action('admin_init', function() {
    // Throttle to once per hour to avoid excessive API calls
    $last_check = get_option('vmpfence_license_last_check', 0);
    $current_time = time();
    
    // Check if 1 hour has passed (3600 seconds)
    if ($current_time - $last_check > 3600) {
        // Ensure required classes are loaded
        if (class_exists('VMPFence_API_Client') && class_exists('VMPFence_License') && class_exists('VMPFence_Config')) {
            try {
                $api_key = VMPFence_Config::get('central_api_key', '');
                if (!empty($api_key)) {
                    $api_client = new VMPFence_API_Client();
                    $license_data = $api_client->check_api_key($api_key);
                    if (!is_wp_error($license_data) && isset($license_data['license_key'])) {
                        VMPFence_License::update_license_settings($license_data);
                    }
                    // Update timestamp regardless of success to prevent retry storm on API failures
                    update_option('vmpfence_license_last_check', $current_time);
                }
            } catch (Exception $e) {
                // Silently fail - license check is not critical
                // Update timestamp even on exception to prevent continuous retries
                update_option('vmpfence_license_last_check', $current_time);
            }
        }
    }
}, 100); // Priority 100 to run after all classes are loaded

/**
 * Plugin activation hook
 *
 * @since 1.0.0
 * @since 2.1.0 -- Early protection file deployment
 * @since 2.2.0 -- GeoIP database import on activation
 * @since 2.2.2 -- Added data retention choice on deactivation default value
 * @since 2.2.4 -- Opcache invalidation after malware signature file creation
 * @return void
 */
function vmpfence_activate() {
    // Check requirements before activation
    if (!vmpfence_check_requirements()) {
        wp_die(
            esc_html__('VMP Security cannot be activated due to minimum requirements not being met.', 'vmpfence-security'),
            esc_html__('Plugin Activation Error', 'vmpfence-security'),
            array('back_link' => true)
        );
    }

    // Deploy early protection file to mu-plugins
    $source = VMPFENCE_PLUGIN_DIR . 'mu-plugins/vmpfence-early-protection.php';
    $mu_plugins_dir = WP_CONTENT_DIR . '/mu-plugins';
    $destination = $mu_plugins_dir . '/vmpfence-early-protection.php';
    
    // Create mu-plugins directory if it doesn't exist
    if (!file_exists($mu_plugins_dir)) {
        wp_mkdir_p($mu_plugins_dir);
    }
    
    // Copy early protection file
    if (file_exists($source)) {
        copy($source, $destination);
    }

    // Load the activation class
    require_once VMPFENCE_PLUGIN_DIR . 'lib/class-database.php';
    require_once VMPFENCE_PLUGIN_DIR . 'lib/class-config.php';
    require_once VMPFENCE_PLUGIN_DIR . 'lib/class-utils.php';
    require_once VMPFENCE_PLUGIN_DIR . 'lib/class-audit-log.php';
    
    // Create malware signatures file from encoded data if neither PHP nor JSON exists
    // (Conflict #5 fix: no longer relies on eager-load side effect of get_instance())
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-signature-loader.php';
    $sig_loader = VMPFence_Signature_Loader::get_instance();
    $sig_loader->ensure_signatures_exist();
    
    // One-time migration: convert existing JSON to PHP array file for opcache
    $json_sig_path = VMPFENCE_PLUGIN_DIR . 'data/malware-signatures.json';
    $php_sig_path  = VMPFENCE_PLUGIN_DIR . 'data/malware-signatures.php';
    if (file_exists($json_sig_path) && !file_exists($php_sig_path)) {
        // Raise memory limit for this one-time conversion
        @ini_set('memory_limit', '512M'); // phpcs:ignore WordPress.PHP.IniSet.memory_limit_Blacklisted
        $json_content = @file_get_contents($json_sig_path);
        if ($json_content !== false) {
            $data = json_decode($json_content, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($data)) {
                $sigs = isset($data['signatures']) ? $data['signatures'] : array();
                $count = count($sigs);
                $php_content = "<?php\n"
                    . "// Auto-generated by VMPFence activation migration — do not edit\n"
                    . "// Migrated: " . gmdate('c') . " | Count: " . $count . "\n"
                    . "return " . var_export(array('count' => $count, 'signatures' => $sigs), true) . ";\n";
                @file_put_contents($php_sig_path, $php_content, LOCK_EX);
                if (function_exists('opcache_invalidate')) {
                    opcache_invalidate($php_sig_path, true);
                }
                // Write metadata sidecar file
                $tier = VMPFence_Config::get('scanner_license_tier', 'free');
                VMPFence_Signature_Loader::write_meta_file($count, $tier, 'php');
                unset($data, $sigs, $php_content, $json_content); // Free memory
            }
        }
    }

    // Create all database tables (comprehensive check)
    VMPFence_Database::create_tables();
    
    // Verify and create any missing tables
    VMPFence_Database::verify_and_create_tables();
    
    // Migrate blocked IPs table (add is_active and source columns, convert data types)
    VMPFence_Database::migrate_blocked_ips_table();
    
    // Set default configuration for custom patterns
    global $wpdb;
    $existing_config = $wpdb->get_var($wpdb->prepare(
        "SELECT val FROM {$wpdb->prefix}vmpfence_config WHERE name = %s",
        'custom_patterns_enabled'
    ));
    
    if ($existing_config === null) {
        $wpdb->insert(
            $wpdb->prefix . 'vmpfence_config',
            array('name' => 'custom_patterns_enabled', 'val' => '1'),
            array('%s', '%s')
        );
    }
    
    // Reset core file hashes on plugin update (for exclusion system)
    // This allows the scanner to recompute baselines after legitimate updates
    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-exclusion-system.php';
    $exclusion_system = new VMPFence_Exclusion_System();
    $exclusion_system->reset_core_file_hashes();
    
    // Create YARA Scanner trusted hashes table
    if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-trusted-hashes-db.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'includes/class-trusted-hashes-db.php';
        VMPFence_Trusted_Hashes_DB::create_table();
    }
    
    // Load Country Blocking classes (required for table creation)
    if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-geoip-lookup.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'includes/class-geoip-lookup.php';
    }
    if (file_exists(VMPFENCE_PLUGIN_DIR . 'firewall/models/class-blocked-country.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-blocked-country.php';
    }
    
    // Create GeoIP database table (Phase 1.5)
    if (class_exists('VMPFence_GeoIP_Lookup')) {
        VMPFence_GeoIP_Lookup::create_table();
        VMPFence_GeoIP_Lookup::schedule_updates();
        
        // Import GeoIP database on activation (download ~500K IP ranges from IP2Location)
        // This is a one-time operation that takes 30-60 seconds
        set_transient('vmpfence_geoip_import_attempted', date('Y-m-d H:i:s'), DAY_IN_SECONDS);
        
        $import_result = VMPFence_GeoIP_Lookup::import_database();
        
        if ($import_result['success']) {
            set_transient('vmpfence_geoip_import_success', $import_result, DAY_IN_SECONDS);
            if (class_exists('VMPFence_Secure_Logger')) {
                VMPFence_Secure_Logger::log('info', 'GeoIP database imported successfully on activation', array(
                    'imported_count' => $import_result['imported_count'],
                    'message' => $import_result['message']
                ));
            }
        } else {
            set_transient('vmpfence_geoip_import_error', $import_result, DAY_IN_SECONDS);
            if (class_exists('VMPFence_Secure_Logger')) {
                VMPFence_Secure_Logger::log('warning', 'GeoIP database import failed on activation', array(
                    'error' => $import_result['message']
                ));
            }
        }
    }
    
    // Install WAF rules (force clear existing rules on activation)
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-waf-rule.php';
    require_once VMPFENCE_PLUGIN_DIR . 'firewall/models/class-rule-importer.php';
    $installed_rules = VMPFence_WAF_Rule::install_default_rules(true);

    // Set default configuration
    VMPFence_Config::set_defaults();
    
    // Ensure critical firewall settings are set (in case they weren't in defaults)
    if (VMPFence_Config::get('realtime_ip_blocklist_enabled') === null) {
        VMPFence_Config::set('realtime_ip_blocklist_enabled', 1);
    }
    
    // Initialize scan options configuration
    VMPFence_Scan_Config::initializeScanOptions();

    // ❌ REMOVED: Automatic API registration - License setup now handled via setup wizard
    // Users must get a license from vmpsecurity.com/pricing/ (FREE or PREMIUM)
    // and activate it via the license setup wizard that appears after activation.
    
    // ⚠️ MOVED: WAF sync moved to AFTER license setup - will run when user activates license
    // The WAF sync will be triggered automatically when the user completes license activation
    // in the setup wizard. This ensures we have a valid API key before attempting to sync rules.
    
    // Schedule initial data syncs to run shortly after activation
    // This prevents blocking activation and provides better UX
    // Syncs will run automatically within 30 seconds via WordPress cron
    $sync_time = time() + 30; // Run 30 seconds after activation
    
    // 1. Schedule blocked IP sync
    if (class_exists('VMPFence_Blocked_IP')) {
        wp_schedule_single_event($sync_time, 'vmpfence_hourly_blocked_ip_sync');
    }
    
    // 2. Schedule malware signature sync
    if (class_exists('VMPFence_Signature_Sync')) {
        wp_schedule_single_event($sync_time + 10, 'vmpfence_hourly_signature_sync');
    }
    
    // 3. WAF rules already synced immediately above (if successful)
    // Scheduled sync below serves as backup in case immediate sync failed
    // Note: Hourly recurring sync is scheduled separately (see cron registration section)
    if (!isset($waf_sync_attempted) || (isset($waf_sync_result) && empty($waf_sync_result['success']))) {
        // Only schedule if immediate sync wasn't attempted or failed
        wp_schedule_single_event($sync_time + 20, 'vmpfence_hourly_waf_sync');
    }
    
    if (class_exists('VMPFence_Secure_Logger')) {
        VMPFence_Secure_Logger::log('info', 'Initial syncs scheduled to run within 1 minute');
    }

    // Set activation flag
    update_option('vmpfence_activation_time', time());
    update_option('vmpfence_version', VMPFENCE_VERSION);
    update_option('vmpfence_db_version', VMPFENCE_DB_VERSION);
    
    // Enable data retention choice on deactivation by default
    add_option('vmpfence_enable_deactivation_choice', 1);
    
    // CRITICAL: Set safe default for data preservation on first activation only
    // Use add_option (not update_option) so we DON'T override user's explicit choice
    // from modal during previous deactivation session
    // Default to 'keep' (true) for safety on fresh installs
    add_option('vmpfence_preserve_data_on_uninstall', true);
    
    // ✅ FIXED FLOW: Check local storage first, then decide action
    // CORRECT BEHAVIOR:
    // - Fresh install → Show setup wizard (user enters license)
    // - Reinstall with data → Use local API key
    // CRITICAL: Check ONLY for local API key to determine fresh install vs existing setup
    // The plugin must ONLY check local data, not rely on flags
    // 
    // If API key exists locally → Plugin has been set up, no wizard needed
    // If NO API key locally → Fresh install, show setup wizard (don't call server)
    
    // Load config class to check for API key
    if (!class_exists('VMPFence_Config')) {
        require_once VMPFENCE_PLUGIN_DIR . 'lib/class-config.php';
    }
    if (!class_exists('VMPFence_Constants')) {
        require_once VMPFENCE_PLUGIN_DIR . 'lib/class-constants.php';
    }
    
    // Check BOTH locations (config table AND WordPress option) for maximum reliability
    $existing_api_key = VMPFence_Config::get('central_api_key', '');
    if (empty($existing_api_key)) {
        // Fallback to WordPress option if not in config table
        $existing_api_key = get_option('vmpfence_central_api_key', '');
    }

    if (empty($existing_api_key)) {
        // NO LOCAL API KEY = FRESH INSTALL
        // Don't call server, don't check any flags
        // Just show setup wizard and let user enter email + license
        // error_log('VMPFence: No local API key found - Fresh installation, showing setup wizard');
    } else {
        // HAS LOCAL API KEY = ALREADY SET UP
        // Plugin has data, no setup needed
        // error_log('VMPFence: Local API key found - Plugin already configured, skipping setup wizard');
    }

    // Set first-time setup flag if we still don't have valid credentials
    if (empty($existing_api_key)) {
        update_option('vmpfence_needs_setup', true);
        // Set transient to show activation modal on plugin pages (Wordfence-style onboarding)
        set_transient('vmpfence_show_activation_modal', true, 300); // 5 minutes
        // Clear any previous dismissal so modal shows on fresh activation
        delete_user_meta(get_current_user_id(), 'vmpfence_dismissed_activation_modal');
    } else {
        // We have API key - clear setup flags and mark setup as completed
        delete_option('vmpfence_needs_setup');
        delete_transient('vmpfence_show_activation_modal');
        update_option('vmpfence_setup_completed', true); // Mark for future recovery
    }

    // Schedule first scan
    if (!wp_next_scheduled('vmpfence_daily_scan')) {
        wp_schedule_event(time() + 3600, 'daily', 'vmpfence_daily_scan');
    }

    // Schedule cleanup
    if (!wp_next_scheduled('vmpfence_cleanup')) {
        wp_schedule_event(time() + 86400, 'daily', 'vmpfence_cleanup');
    }

    // Schedule human cache cleanup (daily)
    if (!wp_next_scheduled('vmpfence_cleanup_human_cache')) {
        wp_schedule_event(time() + 86400, 'daily', 'vmpfence_cleanup_human_cache');
    }
    
    // Schedule hourly blocked IP sync (stagger 10 minutes after hour)
    if (!wp_next_scheduled('vmpfence_hourly_blocked_ip_sync')) {
        wp_schedule_event(time() + 600, 'hourly', 'vmpfence_hourly_blocked_ip_sync');
    }
    
    // Schedule hourly signature sync (stagger 30 minutes after hour)
    if (!wp_next_scheduled('vmpfence_hourly_signature_sync')) {
        wp_schedule_event(time() + 1800, 'hourly', 'vmpfence_hourly_signature_sync');
    }
    
    // Schedule hourly WAF rule sync (stagger 40 minutes after hour, premium only)
    if (!wp_next_scheduled('vmpfence_hourly_waf_sync')) {
        wp_schedule_event(time() + 2400, 'hourly', 'vmpfence_hourly_waf_sync');
    }
    
    // Schedule hourly event sync to API (stagger 50 minutes after hour)
    if (!wp_next_scheduled('vmpfence_daily_sync')) {
        wp_schedule_event(time() + 3000, 'hourly', 'vmpfence_daily_sync');
    }

    // Initialize scheduled scanning system
    if (class_exists('VMPFence_Scan_Scheduler')) {
        $scheduler = VMPFence_Scan_Scheduler::shared();
        
        // Schedule automatic schedule generator (runs daily to update schedules)
        if (!wp_next_scheduled(VMPFence_Constants::CRON_SCHEDULE_GENERATOR)) {
            wp_schedule_event(time() + 3600, 'daily', VMPFence_Constants::CRON_SCHEDULE_GENERATOR);
        }
        
        // Generate initial schedule if user has scheduled scanning enabled
        if (VMPFence_Config::get('scheduledScansEnabled', 1)) {
            $scheduler->initializeScheduling();
        }
    }

    // DB v2.3.0: Run SIEM database upgrade (adds synced columns to 6 tables + 4 new tables)
    if (class_exists('VmpFence_DB_Upgrade')) {
        VmpFence_DB_Upgrade::upgrade();
    }

    // DB v2.3.0: Get site UUID from server
    if (class_exists('VmpFence_Installation')) {
        $site_uuid = VmpFence_Installation::get_installation_uuid(true);
        if ($site_uuid) {
            if (class_exists('VMPFence_Secure_Logger')) {
                VMPFence_Secure_Logger::log('info', 'Site UUID obtained on activation: ' . substr($site_uuid, 0, 8) . '...');
            }
        } else {
            // Schedule retry in 60 seconds
            wp_schedule_single_event(time() + 60, 'vmpfence_retry_identification');
        }
    }

    // DB v2.3.0: Schedule SIEM sync (every 5 minutes)
    if (!wp_next_scheduled('vmpfence_siem_sync')) {
        wp_schedule_event(time() + 300, 'vmpfence_5min', 'vmpfence_siem_sync');
    }

    // Flush rewrite rules
    flush_rewrite_rules();

    // Set transient for activation notice
    set_transient('vmpfence_activation_notice', true, 30);
}

/**
 * Plugin deactivation hook
 *
 * @since 1.0.0
 * @since 2.1.1 Added critical fixes to clear async scan worker and scan-related transients
 * @since 2.2.2 Added optional removal of early protection file on deactivation, data retention choice handling, and data retention option removal
 * @return void
 */
function vmpfence_deactivate() {
    // Clear scheduled events
    wp_clear_scheduled_hook('vmpfence_daily_scan');
    wp_clear_scheduled_hook('vmpfence_cleanup');
    
    // Clear new VMPFence scheduled scanning events
    wp_clear_scheduled_hook(VMPFence_Constants::CRON_SCHEDULE_GENERATOR);
    wp_clear_scheduled_hook(VMPFence_Constants::CRON_SCHEDULED_SCAN);
    
    // Clear human cache cleanup
    wp_clear_scheduled_hook('vmpfence_cleanup_human_cache');
    
    // Clear blocked IP scheduler cron (real-time IP blocklist)
    wp_clear_scheduled_hook('vmpfence_hourly_blocked_ip_sync');
    
    // Clear signature scheduler cron (malware signature sync)
    wp_clear_scheduled_hook('vmpfence_hourly_signature_sync');
    
    // Clear WAF rule scheduler cron (firewall rule sync)
    wp_clear_scheduled_hook('vmpfence_hourly_waf_sync');
    
    // Clear GeoIP database update cron (monthly GeoIP updates)
    wp_clear_scheduled_hook('vmpfence_geoip_update');
    
    // Clear event sync cron
    wp_clear_scheduled_hook('vmpfence_daily_sync');
    
    // Clear SIEM sync crons (DB v2.3.0)
    wp_clear_scheduled_hook('vmpfence_siem_sync');
    wp_clear_scheduled_hook('vmpfence_retry_identification');
    
    // Clear all individual scheduled scans if scheduler exists
    if (class_exists('VMPFence_Scan_Scheduler')) {
        $scheduler = VMPFence_Scan_Scheduler::shared();
        $scheduler->unscheduleAllScans();
    }
    
    // Clear scan monitoring cron
    if (class_exists('VMPFence_Scan_Monitor')) {
        VMPFence_Scan_Monitor::handleDeactivation();
    }
    
    // CRITICAL FIX: Clear async scan worker cron
    wp_clear_scheduled_hook('vmpfence_async_scan_worker');
    
    // CRITICAL FIX: Clear all scan-related transients and locks
    // This prevents old scans from resuming after reactivation
    delete_transient('vmpfence_scan_lock');
    delete_transient('vmpfence_processed_plugins');
    delete_transient('vmpfence_processed_themes');
    delete_transient('vmpfence_scan_needs_resume');
    
    // Clear scan progress data
    delete_option('vmpfence_scan_progress');
    delete_option('vmpfence_last_scan_debug_logs');
    
    // Clear any other scan-related transients (wildcard cleanup)
    global $wpdb;
    $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_vmpfence_scan_%' OR option_name LIKE '_transient_timeout_vmpfence_scan_%'");
    
    // Optionally remove early protection file from mu-plugins
    // Keep commented to preserve protection even after deactivation
    // Uncomment the following lines if you want to remove it on deactivation:
    $mu_plugins_file = WP_CONTENT_DIR . '/mu-plugins/vmpfence-early-protection.php';
    if (file_exists($mu_plugins_file)) {
        unlink($mu_plugins_file);
    }

    // Flush rewrite rules
    flush_rewrite_rules();

    // Clear all scheduled cron jobs (CRITICAL: prevents errors when plugin is deactivated)
    // These jobs will be rescheduled on reactivation
    $cron_hooks = array(
        'vmpfence_daily_scan',
        'vmpfence_cleanup',
        'vmpfence_cleanup_human_cache',
        'vmpfence_hourly_blocked_ip_sync',
        'vmpfence_hourly_signature_sync',
        'vmpfence_sync_signatures', // Legacy orphan hook from VMPFence_Signature_Loader (deprecated 2.2.3)
        'vmpfence_hourly_waf_sync',
        'vmpfence_daily_sync',
        'vmpfence_hourly_firewall_rules_sync',
        'vmpfence_daily_threat_intel_sync',
        'vmpfence_weekly_security_report',
        'vmpfence_cleanup_old_logs',
        'vmpfence_daily_license_check',
        'vmpfence_siem_sync',
        'vmpfence_retry_identification',
    );
    
    // Also clear dynamic scan schedules if constants are available
    if (defined('VMPFENCE_PLUGIN_DIR') && file_exists(VMPFENCE_PLUGIN_DIR . 'lib/class-constants.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'lib/class-constants.php';
        if (defined('VMPFence_Constants::CRON_SCHEDULE_GENERATOR')) {
            $cron_hooks[] = VMPFence_Constants::CRON_SCHEDULE_GENERATOR;
        }
    }
    
    foreach ($cron_hooks as $hook) {
        $timestamp = wp_next_scheduled($hook);
        if ($timestamp) {
            wp_unschedule_event($timestamp, $hook);
        }
        // Also clear any other instances
        wp_clear_scheduled_hook($hook);
    }
    
    // Clear all dynamic scan schedules (these use dynamic hook names)
    wp_clear_scheduled_hook('vmpfence_scheduled_scan_quick');
    wp_clear_scheduled_hook('vmpfence_scheduled_scan_standard');
    wp_clear_scheduled_hook('vmpfence_scheduled_scan_complete');

    // Check if tables will be deleted (to prevent audit log DB error)
    $enable_deactivation_choice = get_option('vmpfence_enable_deactivation_choice', 0);
    $will_delete_tables = false;
    if ($enable_deactivation_choice) {
        $data_action = get_transient('vmpfence_deactivation_data_action');
        $will_delete_tables = ($data_action === 'delete');
    }
    
    // Phase 1: Delete Login Security data if user enabled the setting
    if (file_exists(VMPFENCE_PLUGIN_DIR . 'includes/class-login-security-features.php')) {
        require_once VMPFENCE_PLUGIN_DIR . 'includes/class-login-security-features.php';
        
        if (VMPFence_Login_Security_Features::should_delete_on_deactivate()) {
            VMPFence_Login_Security_Features::cleanup_data();
        }
    }
    
    // Phase 2: Check for data retention choice (if enabled in All Options)
    
    if ($enable_deactivation_choice) {
        // Get the data action choice from the transient set by feedback modal
        $data_action = get_transient('vmpfence_deactivation_data_action');
        
        // Delete the transient after reading it
        // delete_transient('vmpfence_deactivation_data_action');
        
        // If user chose to delete all data
        if ($data_action === 'delete') {
            // Load required classes
            require_once VMPFENCE_PLUGIN_DIR . 'lib/class-constants.php';
            require_once VMPFENCE_PLUGIN_DIR . 'lib/class-database.php';
            require_once VMPFENCE_PLUGIN_DIR . 'lib/class-config.php';
            
            // Remove database tables
            VMPFence_Database::drop_tables();

            // Ensure all vmpfence tables are dropped (including any missed ones)
            global $wpdb;
            $like = $wpdb->esc_like($wpdb->prefix . 'vmpfence_') . '%';
            $all_tables = $wpdb->get_results($wpdb->prepare('SHOW TABLES LIKE %s', $like), ARRAY_N);
            foreach ($all_tables as $table) {
                if (empty($table[0])) {
                    continue;
                }
                $table_name = $table[0];
                $result = $wpdb->query("DROP TABLE IF EXISTS `{$table_name}`"); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                // if ($result === false) {
                //     error_log('VMPFence Deactivation: ERROR dropping table: ' . $table_name . ' - ' . $wpdb->last_error);
                // } else {
                //     error_log('VMPFence Deactivation: Successfully dropped table: ' . $table_name);
                // }
            }
            
            // Verify all tables are deleted
            $remaining_tables = $wpdb->get_results($wpdb->prepare('SHOW TABLES LIKE %s', $like), ARRAY_N);
            
            // Remove all options
            VMPFence_Config::remove_all_options();
            
            // Remove all user meta related to VMP Security
            // This ensures fresh install flow on reactivation
            global $wpdb;
            $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE 'vmpfence_%'");
            
            // Remove upload directory
            $upload_dir = wp_upload_dir()['basedir'] . '/vmpfence/';
            if (is_dir($upload_dir)) {
                vmpfence_remove_directory($upload_dir);
            }
        }
        // Delete after 5 seconds to ensure all WordPress hooks have finished
        set_transient('vmpfence_cleanup_deactivation_transient', true, 5);
        // If 'keep' or not set, preserve all data (do nothing)
    }
}

/**
 * Plugin uninstall hook
 *
 * @since 1.0.0
 * @since 2.1.2 Added removal of mu-plugins file and directory
 * @return void
 */
function vmpfence_uninstall() {
    // Load required classes
    require_once VMPFENCE_PLUGIN_DIR . 'lib/class-database.php';
    require_once VMPFENCE_PLUGIN_DIR . 'lib/class-config.php';
    require_once VMPFENCE_PLUGIN_DIR . 'lib/class-utils.php';
    require_once VMPFENCE_PLUGIN_DIR . 'lib/class-audit-log.php';

    // Check if user wants to preserve data
    // Default to TRUE (keep) for safety - matches uninstall.php behavior
    $preserve_data = get_option('vmpfence_preserve_data_on_uninstall', true);

    if (!$preserve_data) {
        // Remove database tables
        VMPFence_Database::drop_tables();
        // Remove all options
        VMPFence_Config::remove_all_options();
        // Clean up deactivation-related options (not in remove_all_options to avoid deletion during deactivation)
        delete_option('vmpfence_enable_deactivation_choice');

        // Remove upload directory
        vmpfence_remove_directory(wp_upload_dir()['basedir'] . '/vmpfence/');
    }
    
    // Remove early protection file from mu-plugins (always, even if preserving data)
    $mu_plugins_file = WP_CONTENT_DIR . '/mu-plugins/vmpfence-early-protection.php';
    if (file_exists($mu_plugins_file)) {
        unlink($mu_plugins_file);
    }
    
    // Remove mu-plugins directory if it's empty
    $mu_plugins_dir = WP_CONTENT_DIR . '/mu-plugins';
    if (is_dir($mu_plugins_dir)) {
        $files = array_diff(scandir($mu_plugins_dir), array('.', '..'));
        if (empty($files)) {
            rmdir($mu_plugins_dir);
        }
    }

    // Clear any remaining scheduled events
    wp_clear_scheduled_hook('vmpfence_daily_scan');
    wp_clear_scheduled_hook('vmpfence_cleanup');

    // Remove rewrite rules
    flush_rewrite_rules();
}

/**
 * Remove directory and all contents
 *
 * @since 1.0.0
 * @param string $dir Directory path
 * @return bool
 */
function vmpfence_remove_directory($dir) {
    if (!is_dir($dir)) {
        return false;
    }

    $files = array_diff(scandir($dir), array('.', '..'));
    foreach ($files as $file) {
        $path = $dir . DIRECTORY_SEPARATOR . $file;
        if (is_dir($path)) {
            vmpfence_remove_directory($path);
        } else {
            unlink($path);
        }
    }

    // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- Required for recursive directory removal during uninstall
    return rmdir($dir);
}

// Register hooks
register_activation_hook(__FILE__, 'vmpfence_activate');
register_deactivation_hook(__FILE__, 'vmpfence_deactivate');
register_uninstall_hook(__FILE__, 'vmpfence_uninstall');

// Initialize plugin
add_action('plugins_loaded', 'vmpfence_init');

// CRITICAL: Register background scan fork handler for async scanning
// This hook is called by WP-Cron when a scan is started in background mode
add_action('vmpfence_monitor_fork_scan', 'vmpfence_handle_monitor_fork_scan');

/**
 * Handle background scan execution via WP-Cron
 * @since 2.1.1 Added critical fixes to clear async scan worker and scan-related transients
 * @param string $scan_type Type of scan to execute
 */
function vmpfence_handle_monitor_fork_scan($scan_type = 'standard') {
    // Load scan scheduler if not already loaded
    if (!class_exists('VMPFence_Scan_Scheduler')) {
        require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-scheduler.php';
    }
    
    // Execute the scan via scheduler's fork handler
    VMPFence_Scan_Scheduler::handleMonitorForkScan($scan_type);
}

// Hook into user role changes to track admin additions
add_action('set_user_role', 'vmpfence_track_user_role_change', 10, 3);
add_action('add_user_role', 'vmpfence_track_user_role_add', 10, 2);
add_action('remove_user_role', 'vmpfence_track_user_role_remove', 10, 2);

// Hook into multisite super admin changes
add_action('granted_super_admin', 'vmpfence_track_super_admin_grant', 10, 1);
add_action('revoked_super_admin', 'vmpfence_track_super_admin_revoke', 10, 1);

/**
 * Track when user role changes to/from administrator
 * 
 */
function vmpfence_track_user_role_change($user_id, $role, $old_roles) {
    if (!class_exists('VMPFence_User_Security_Scanner')) {
        return;
    }
    
    $scanner = new VMPFence_User_Security_Scanner();
    
    if ($role === 'administrator' && !in_array('administrator', $old_roles)) {
        // User became admin - add to baseline
        $scanner->add_admin_to_baseline($user_id);
    } elseif ($role !== 'administrator' && in_array('administrator', $old_roles)) {
        // User no longer admin - remove from baseline
        $scanner->remove_admin_from_baseline($user_id);
    }
}

/**
 * Track when user gains administrator role
 */
function vmpfence_track_user_role_add($user_id, $role) {
    if ($role === 'administrator' && class_exists('VMPFence_User_Security_Scanner')) {
        $scanner = new VMPFence_User_Security_Scanner();
        $scanner->add_admin_to_baseline($user_id);
    }
}

/**
 * Track when user loses administrator role
 */
function vmpfence_track_user_role_remove($user_id, $role) {
    if ($role === 'administrator' && class_exists('VMPFence_User_Security_Scanner')) {
        $scanner = new VMPFence_User_Security_Scanner();
        $scanner->remove_admin_from_baseline($user_id);
    }
}

/**
 * Track when user becomes super admin
 */
function vmpfence_track_super_admin_grant($user_id) {
    if (class_exists('VMPFence_User_Security_Scanner')) {
        $scanner = new VMPFence_User_Security_Scanner();
        $scanner->add_admin_to_baseline($user_id);
    }
}

/**
 * Track when user loses super admin
 */
function vmpfence_track_super_admin_revoke($user_id) {
    if (class_exists('VMPFence_User_Security_Scanner')) {
        $scanner = new VMPFence_User_Security_Scanner();
        $scanner->remove_admin_from_baseline($user_id);
    }
}


