<?php
/**
 * Abstract Audit Log Observer Base Class
 *
 * All observer classes extend this. Provides mode-gating, severity filtering,
 * preview-mode sampling, and the shared log() helper that delegates to
 * VMPFence_Audit_Log::log_event().
 *
 * @package VMPFence
 * @since 2.2.5
 * @since 2.2.6 Block cleared for blocks fixed
 */

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

abstract class VMPFence_Audit_Log_Observer {

    /**
     * Current logging mode (disabled | preview | significant | all)
     *
     * @var string
     */
    protected $logging_mode;

    /**
     * Constructor — reads the current logging mode once.
     */
    public function __construct() {
        $this->logging_mode = get_option('vmpfence_audit_log_logging_mode', 'preview');
    }

    /**
     * Register WordPress / VMPFence hooks.
     * Each concrete observer implements this with its own add_action() calls.
     *
     * @return void
     */
    abstract public function register_hooks();

    // =========================================================================
    // LOGGING
    // =========================================================================

    /**
     * Log an event through VMPFence_Audit_Log, respecting mode + severity.
     *
     * @param string $event_type  Event identifier (e.g. 'user_registered').
     * @param array  $data        Arbitrary context to store with the event.
     * @param string $severity    One of: info | warning | critical
     * @return void
     */
    protected function log($event_type, $data = array(), $severity = 'info') {
        // ----- Mode: disabled — never log -----
        if ($this->logging_mode === 'disabled') {
            return;
        }

        // ----- Mode: preview — check sampling flag -----
        if ($this->logging_mode === 'preview') {
            if (defined('VMPFence_Constants::PREVIEW_MODE_SAMPLING')
                && VMPFence_Constants::PREVIEW_MODE_SAMPLING) {
                if (!in_array($event_type, self::get_preview_sampled_events(), true)) {
                    return;
                }
            }
            // When PREVIEW_MODE_SAMPLING is false (default) → log everything
        }

        // ----- Mode: significant — skip info-level events unless allowlisted -----
        if ($this->logging_mode === 'significant' && $severity === 'info') {
            if (!in_array($event_type, self::get_significant_events(), true)) {
                return;
            }
        }

        // Attach metadata
        $data['severity'] = $severity;
        $data['observer'] = static::class;

        VMPFence_Audit_Log::log_event($event_type, $data);
    }

    // =========================================================================
    // HELPERS
    // =========================================================================

    /**
     * Get the current logged-in user's basic info.
     *
     * @return array{user_id: int, username: string, roles: string[]}
     */
    protected function get_current_user_info() {
        $user = wp_get_current_user();
        return array(
            'user_id'  => $user->ID,
            'username' => $user->user_login ?: '',
            'roles'    => $user->roles ?: array(),
        );
    }

    /**
     * Get the client's real IP address using VMPFence_Utils when available.
     *
     * @return string
     */
    protected function get_client_ip() {
        if (class_exists('VMPFence_Utils')) {
            $utils = new VMPFence_Utils();
            if (method_exists($utils, 'get_real_ip')) {
                return $utils->get_real_ip();
            }
        }
        return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'unknown';
    }

    // =========================================================================
    // PREVIEW SAMPLING
    // =========================================================================

    /**
     * Critical events that are still logged when preview-mode sampling is ON.
     * ~35 events covering user, site, plugin/theme, VMPFence config, multisite.
     *
     * @return string[]
     */
    public static function get_preview_sampled_events() {
        return array(
            // User / Auth
            'user_registered',
            'user_deleted',
            'user_role_changed',
            'login_success',
            'login_failure',
            'password_reset',
            'app_password_created',

            // Site / Options
            'option_siteurl_changed',
            'option_home_changed',
            'option_admin_email_changed',
            'option_default_role_changed',
            'option_registration_changed',

            // Plugins & Themes
            'plugin_activated',
            'plugin_deactivated',
            'plugin_installed',
            'plugin_deleted',
            'theme_changed',
            'theme_installed',
            'theme_deleted',

            // Core
            'core_updated',
            'auto_updates_completed',

            // Site actions
            'file_editor_used',
            'recovery_key_generated',
            'site_data_exported',
            'customizer_saved',

            // VMPFence config (critical)
            'vmpfence_waf_mode_changed',
            'vmpfence_waf_blocklist_toggled',
            'vmpfence_brute_force_toggled',
            'vmpfence_audit_log_mode_changed',
            'vmpfence_license_changed',
            'config_imported',

            // Blocking / unblocking
            'ip_blocked',
            'vmpfence_ip_unblocked',
            'vmpfence_country_blocked',
            'vmpfence_country_unblocked',

            // Multisite
            'multisite_site_created',
            'multisite_site_deleted',
            'multisite_super_admin_granted',
            'multisite_super_admin_revoked',
        );
    }

    /**
     * Events that are always logged in "significant" mode even when their
     * severity is 'info'. These are security-relevant events that users
     * always expect to see in the audit trail.
     *
     * @return string[]
     */
    public static function get_significant_events() {
        return array(
            // Authentication — always significant
            'login_success',
            'login_failure',
            'user_logout',
            'password_reset',
            'password_reset_requested',
            'auth_cookie_set',
            'app_password_created',
            'app_password_used',

            // User lifecycle
            'user_registered',
            'user_profile_updated',

            // Content lifecycle
            'post_published',
            'post_deleted',
            'media_uploaded',

            // Site lifecycle
            'plugin_activated',
            'plugin_deactivated',
            'theme_changed',
            'core_updated',
            'mail_sent',
            'mail_failed',
            'file_editor_used',

            // VMPFence
            'config_imported',
            'config_exported',
            'config_reset',
            'backup_created',
            'backup_restored',
            'scheduled_scan_started',
        );
    }
}
