<?php
/**
 * WAF Rule Scheduler - Manages automatic hourly sync from API
 *
 * @package VMPFence
 * @since 2.1.2
 */

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

/**
 * VMPFence WAF Rule Scheduler Class
 * 
 * Handles scheduling and management of automatic WAF rule syncing from API.
 * Premium-tier feature that ensures firewall rules are always up-to-date.
 *
 * @since 2.1.2
 */
class VMPFence_WAF_Rule_Scheduler {

    /**
     * Cron hook name for hourly sync
     */
    const CRON_HOOK = 'vmpfence_hourly_waf_sync';

    /**
     * Initialize the scheduler
     * Sets up WordPress action hooks for cron management
     *
     * @since 2.1.2
     * @return void
     */
    public static function init() {
        // Hook to handle the actual sync when cron runs
        add_action(self::CRON_HOOK, array(__CLASS__, 'run_scheduled_sync'));
        
        // Hook to ensure cron state matches premium tier on plugin load
        add_action('plugins_loaded', array(__CLASS__, 'ensure_cron_state'), 20);
    }

    /**
     * Ensure cron job state matches the premium tier status
     * Called on plugin load to sync cron with license tier
     *
     * @since 2.1.2
     * @return void
     */
    public static function ensure_cron_state() {
        $should_sync = self::should_sync();
        $is_scheduled = self::is_scheduled();

        if ($should_sync && !$is_scheduled) {
            // Premium tier and not scheduled - schedule it
            self::schedule_sync();
        } elseif (!$should_sync && $is_scheduled) {
            // Not premium or disabled - unschedule it
            self::unschedule_sync();
        }
    }

    /**
     * Check if WAF rule sync should be active
     * Only active for premium tier with firewall enabled
     *
     * @since 2.1.2
     * @return bool True if should sync, false otherwise
     */
    public static function should_sync() {
        // Check if API is available
        if (!class_exists('VMPFence_Config') || !VMPFence_Config::is_api_available()) {
            return false;
        }

        // Check if firewall license tier is premium
        $firewall_tier = VMPFence_Config::get('firewall_license_tier', 'free');
        
        // WAF rule sync is only available for premium tier
        return ($firewall_tier === 'premium');
    }

    /**
     * Check if cron job is currently scheduled
     *
     * @since 2.1.2
     * @return bool True if scheduled, false otherwise
     */
    public static function is_scheduled() {
        return (bool) wp_next_scheduled(self::CRON_HOOK);
    }

    /**
     * Schedule the hourly sync cron job
     *
     * @since 2.1.2
     * @return bool True on success, false on failure
     */
    public static function schedule_sync() {
        // Don't schedule if already scheduled
        if (self::is_scheduled()) {
            return true;
        }

        // Don't schedule if not premium
        if (!self::should_sync()) {
            return false;
        }

        // Schedule to run hourly starting now
        $result = wp_schedule_event(time(), 'hourly', self::CRON_HOOK);

        if ($result !== false) {
            if (class_exists('VMPFence_Secure_Logger')) {
                VMPFence_Secure_Logger::log('info', 'Scheduled hourly WAF rule sync', array(
                    'next_run' => date('Y-m-d H:i:s', wp_next_scheduled(self::CRON_HOOK))
                ));
            }
            return true;
        }

        return false;
    }

    /**
     * Unschedule the hourly sync cron job
     *
     * @since 2.1.2
     * @return bool True on success
     */
    public static function unschedule_sync() {
        $timestamp = wp_next_scheduled(self::CRON_HOOK);
        
        if ($timestamp) {
            wp_unschedule_event($timestamp, self::CRON_HOOK);
            if (class_exists('VMPFence_Secure_Logger')) {
                VMPFence_Secure_Logger::log('info', 'Unscheduled hourly WAF rule sync');
            }
        }
        
        // Also clear any orphaned hooks
        wp_clear_scheduled_hook(self::CRON_HOOK);
        
        return true;
    }

    /**
     * Run the scheduled sync (called by WordPress cron)
     * This is the actual function that executes when the cron runs
     *
     * @since 2.1.2
     * @return void
     */
    public static function run_scheduled_sync() {
        // Double-check that sync should still run (tier could have changed)
        if (!self::should_sync()) {
            if (class_exists('VMPFence_Secure_Logger')) {
                VMPFence_Secure_Logger::log('warning', 'WAF rule sync ran but not premium tier - unscheduling');
            }
            self::unschedule_sync();
            return;
        }

        // Check if the WAF rule class exists
        if (!class_exists('VMPFence_WAF_Rule')) {
            if (class_exists('VMPFence_Secure_Logger')) {
                VMPFence_Secure_Logger::log('error', 'WAF Rule class not found');
            }
            return;
        }

        if (class_exists('VMPFence_Secure_Logger')) {
            VMPFence_Secure_Logger::log('info', 'Starting scheduled WAF rule sync');
        }

        // Run the sync
        $result = VMPFence_WAF_Rule::sync_from_api();

        // Save last sync time if successful
        if ($result['success']) {
            VMPFence_Config::set('last_waf_sync_time', time());
        }

        // Log results
        if (class_exists('VMPFence_Secure_Logger')) {
            if ($result['success']) {
                VMPFence_Secure_Logger::log('info', 'Scheduled WAF rule sync completed', array(
                    'total_rules' => $result['total'],
                    'new_rules' => isset($result['new']) ? $result['new'] : 0,
                    'updated_rules' => isset($result['updated']) ? $result['updated'] : 0
                ));
            } else {
                VMPFence_Secure_Logger::log('error', 'Scheduled WAF rule sync failed', array(
                    'errors' => isset($result['errors']) ? $result['errors'] : array('Unknown error')
                ));
            }
        }
    }

    /**
     * Get next scheduled sync time
     *
     * @since 2.1.2
     * @return int|false Unix timestamp of next scheduled run, or false if not scheduled
     */
    public static function get_next_sync_time() {
        return wp_next_scheduled(self::CRON_HOOK);
    }

    /**
     * Get time until next sync in human-readable format
     *
     * @since 2.1.2
     * @return string Human-readable time until next sync, or "Not scheduled" if disabled
     */
    public static function get_next_sync_human() {
        $timestamp = self::get_next_sync_time();
        
        if (!$timestamp) {
            return 'Not scheduled';
        }

        $time_diff = $timestamp - time();
        
        if ($time_diff < 0) {
            return 'Overdue (running soon)';
        }
        
        if ($time_diff < 60) {
            return 'Less than 1 minute';
        }
        
        if ($time_diff < 3600) {
            $minutes = ceil($time_diff / 60);
            return $minutes . ' minute' . ($minutes > 1 ? 's' : '');
        }
        
        $hours = floor($time_diff / 3600);
        $minutes = floor(($time_diff % 3600) / 60);
        
        $result = $hours . ' hour' . ($hours > 1 ? 's' : '');
        if ($minutes > 0) {
            $result .= ' ' . $minutes . ' minute' . ($minutes > 1 ? 's' : '');
        }
        
        return $result;
    }

    /**
     * Manual trigger for sync (bypasses schedule and tier check)
     * Useful for testing or immediate sync needs
     *
     * @since 2.1.2
     * @return array Result from sync_from_api()
     */
    public static function trigger_manual_sync() {
        if (!class_exists('VMPFence_WAF_Rule')) {
            return array(
                'success' => false,
                'total' => 0,
                'error' => 'VMPFence_WAF_Rule class not found'
            );
        }

        if (class_exists('VMPFence_Secure_Logger')) {
            VMPFence_Secure_Logger::log('info', 'Manual WAF rule sync triggered');
        }
        return VMPFence_WAF_Rule::sync_from_api();
    }

    /**
     * Get scheduler status information
     *
     * @since 2.1.2
     * @return array Status information
     */
    public static function get_status() {
        return array(
            'enabled' => self::should_sync(),
            'scheduled' => self::is_scheduled(),
            'premium_tier' => VMPFence_Config::get('firewall_license_tier', 'free') === 'premium',
            'next_run' => self::get_next_sync_time(),
            'next_run_human' => self::get_next_sync_human(),
            'cron_hook' => self::CRON_HOOK
        );
    }

    /**
     * Cleanup method - removes all cron jobs
     * Should be called on plugin deactivation/uninstall
     *
     * @since 2.1.2
     * @return void
     */
    public static function cleanup() {
        wp_clear_scheduled_hook(self::CRON_HOOK);
        if (class_exists('VMPFence_Secure_Logger')) {
            VMPFence_Secure_Logger::log('info', 'Cleaned up WAF rule scheduler cron jobs');
        }
    }
}
