<?php
/**
 * Event Tracking Hooks
 *
 * Automatically logs important security events to the API
 *
 * @package VMPFence
 * @since 2.1.0
 */

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

/**
 * VMPFence Event Tracker Class
 *
 * @since 2.1.0
 */
class VMPFence_Event_Tracker {

    /**
     * Singleton instance
     *
     * @var VMPFence_Event_Tracker
     */
    private static $instance = null;

    /**
     * Logging service instance
     *
     * @var VMPFence_Logging_Service
     */
    private $logging_service;

    /**
     * Get singleton instance
     *
     * @since 2.1.0
     * @return VMPFence_Event_Tracker
     */
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor
     *
     * @since 2.1.0
     */
    private function __construct() {
        require_once VMPFENCE_PLUGIN_DIR . 'lib/class-logging-service.php';
        $this->logging_service = VMPFence_Logging_Service::get_instance();

        $this->register_hooks();
    }

    /**
     * Register WordPress hooks
     *
     * @since 2.1.0
     * @return void
     */
    private function register_hooks() {
        // User events
        add_action('user_register', array($this, 'track_user_registration'));
        add_action('set_user_role', array($this, 'track_role_change'), 10, 3);
        add_action('delete_user', array($this, 'track_user_deletion'));

        // Login events
        add_action('wp_login_failed', array($this, 'track_login_failed'));
        add_action('wp_login', array($this, 'track_successful_login'), 10, 2);

        // Plugin events
        add_action('activated_plugin', array($this, 'track_plugin_activated'));
        add_action('deactivated_plugin', array($this, 'track_plugin_deactivated'));

        // Theme events
        add_action('switch_theme', array($this, 'track_theme_switch'), 10, 3);

        // File upload events
        add_action('add_attachment', array($this, 'track_file_upload'));

        // Core update events
        add_action('_core_updated_successfully', array($this, 'track_core_update'));

        // Options changes (critical settings)
        add_action('update_option_siteurl', array($this, 'track_siteurl_change'), 10, 2);
        add_action('update_option_home', array($this, 'track_home_url_change'), 10, 2);
    }

    // ============================================================================
    // USER EVENT TRACKERS
    // ============================================================================

    /**
     * Track new user registration
     *
     * @since 2.1.0
     * @param int $user_id User ID
     * @return void
     */
    public function track_user_registration($user_id) {
        $user = get_userdata($user_id);
        if (!$user) {
            return;
        }

        $severity = 'info';
        $event_type = 'user_registered';

        // If user is admin, make it critical
        if (in_array('administrator', $user->roles)) {
            $severity = 'critical';
            $event_type = 'admin_user_created';
            
            // Use the dedicated admin user creation logger
            $this->logging_service->log_admin_user_created(
                $user_id,
                $user->user_login,
                $user->user_email
            );
            return;
        }

        $this->logging_service->log_event($event_type, $severity, array(
            'user_id' => $user_id,
            'username' => $user->user_login,
            'email' => $user->user_email,
            'roles' => $user->roles,
        ), 'system');
    }

    /**
     * Track user role changes
     *
     * @since 2.1.0
     * @param int    $user_id User ID
     * @param string $role New role
     * @param array  $old_roles Previous roles
     * @return void
     */
    public function track_role_change($user_id, $role, $old_roles) {
        $user = get_userdata($user_id);
        if (!$user) {
            return;
        }

        $severity = 'info';

        // Elevation to admin is critical
        if ($role === 'administrator' && !in_array('administrator', $old_roles)) {
            $severity = 'critical';
            
            // Log as admin user creation
            $this->logging_service->log_admin_user_created(
                $user_id,
                $user->user_login,
                $user->user_email
            );
            return;
        }

        // Demotion from admin is also critical
        if (in_array('administrator', $old_roles) && $role !== 'administrator') {
            $severity = 'critical';
        }

        $this->logging_service->log_event('user_role_changed', $severity, array(
            'user_id' => $user_id,
            'username' => $user->user_login,
            'old_roles' => $old_roles,
            'new_role' => $role,
        ), 'system');
    }

    /**
     * Track user deletion
     *
     * @since 2.1.0
     * @param int $user_id User ID
     * @return void
     */
    public function track_user_deletion($user_id) {
        $user = get_userdata($user_id);
        if (!$user) {
            return;
        }

        $severity = in_array('administrator', $user->roles) ? 'critical' : 'warning';

        $this->logging_service->log_event('user_deleted', $severity, array(
            'user_id' => $user_id,
            'username' => $user->user_login,
            'email' => $user->user_email,
            'roles' => $user->roles,
        ), 'system');
    }

    // ============================================================================
    // LOGIN EVENT TRACKERS
    // ============================================================================

    /**
     * Track failed login attempts
     *
     * @since 2.1.0
     * @param string $username Username that failed login
     * @return void
     */
    public function track_login_failed($username) {
        $this->logging_service->log_login_failed($username, 'invalid_credentials');
    }

    /**
     * Track successful login
     *
     * @since 2.1.0
     * @param string  $user_login Username
     * @param WP_User $user User object
     * @return void
     */
    public function track_successful_login($user_login, $user) {
        $severity = in_array('administrator', $user->roles) ? 'info' : 'info';

        $this->logging_service->log_event('user_login_success', $severity, array(
            'user_id' => $user->ID,
            'username' => $user_login,
            'roles' => $user->roles,
        ), 'login');
    }

    // ============================================================================
    // PLUGIN EVENT TRACKERS
    // ============================================================================

    /**
     * Track plugin activation
     *
     * @since 2.1.0
     * @param string $plugin Plugin basename
     * @return void
     */
    public function track_plugin_activated($plugin) {
        $plugin_data = $this->get_plugin_data($plugin);

        $this->logging_service->log_plugin_action('activated', $plugin_data['name']);
    }

    /**
     * Track plugin deactivation
     *
     * @since 2.1.0
     * @since 2.2.2 - Avoid logging if tables are being deleted on deactivation
     * @param string $plugin Plugin basename
     * @return void
     */
    public function track_plugin_deactivated($plugin) {
        // Check if tables are being deleted to avoid recreation
        $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') {
                // Tables are being deleted, don't log (would recreate tables)
                return;
            }
        }
        
        $plugin_data = $this->get_plugin_data($plugin);

        $this->logging_service->log_plugin_action('deactivated', $plugin_data['name']);
    }

    /**
     * Get plugin data
     *
     * @since 2.1.0
     * @param string $plugin Plugin basename
     * @return array Plugin data
     */
    private function get_plugin_data($plugin) {
        if (!function_exists('get_plugin_data')) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        $plugin_file = WP_PLUGIN_DIR . '/' . $plugin;
        
        if (file_exists($plugin_file)) {
            $data = get_plugin_data($plugin_file);
            return array(
                'name' => $data['Name'],
                'version' => $data['Version'],
                'slug' => $plugin,
            );
        }

        return array(
            'name' => $plugin,
            'version' => 'unknown',
            'slug' => $plugin,
        );
    }

    // ============================================================================
    // THEME EVENT TRACKERS
    // ============================================================================

    /**
     * Track theme switch
     *
     * @since 2.1.0
     * @param string   $new_name New theme name
     * @param WP_Theme $new_theme New theme object
     * @param WP_Theme $old_theme Old theme object
     * @return void
     */
    public function track_theme_switch($new_name, $new_theme, $old_theme) {
        $this->logging_service->log_event('theme_switched', 'info', array(
            'old_theme' => $old_theme->get('Name'),
            'old_version' => $old_theme->get('Version'),
            'new_theme' => $new_theme->get('Name'),
            'new_version' => $new_theme->get('Version'),
        ), 'system');
    }

    // ============================================================================
    // FILE EVENT TRACKERS
    // ============================================================================

    /**
     * Track file uploads
     *
     * @since 2.1.0
     * @param int $attachment_id Attachment ID
     * @return void
     */
    public function track_file_upload($attachment_id) {
        $file = get_attached_file($attachment_id);
        $file_info = pathinfo($file);
        $file_size = filesize($file);

        // Flag potentially dangerous file types
        $dangerous_extensions = array('php', 'phtml', 'php3', 'php4', 'php5', 'phps', 'exe', 'bat', 'sh', 'cgi');
        $severity = in_array(strtolower($file_info['extension']), $dangerous_extensions) ? 'warning' : 'info';

        $this->logging_service->log_event('file_uploaded', $severity, array(
            'attachment_id' => $attachment_id,
            'filename' => $file_info['basename'],
            'extension' => $file_info['extension'],
            'size_bytes' => $file_size,
            'mime_type' => get_post_mime_type($attachment_id),
        ), 'system');
    }

    // ============================================================================
    // CORE UPDATE TRACKERS
    // ============================================================================

    /**
     * Track WordPress core updates
     *
     * @since 2.1.0
     * @param string $new_version New WordPress version
     * @return void
     */
    public function track_core_update($new_version) {
        global $wp_version;

        $this->logging_service->log_event('wordpress_updated', 'info', array(
            'new_version' => $new_version,
            'old_version' => $wp_version,
        ), 'system');
    }

    // ============================================================================
    // SETTINGS CHANGE TRACKERS
    // ============================================================================

    /**
     * Track site URL changes
     *
     * @since 2.1.0
     * @param string $old_value Old URL
     * @param string $new_value New URL
     * @return void
     */
    public function track_siteurl_change($old_value, $new_value) {
        if ($old_value !== $new_value) {
            $this->logging_service->log_event('siteurl_changed', 'critical', array(
                'old_url' => $old_value,
                'new_url' => $new_value,
            ), 'system');
        }
    }

    /**
     * Track home URL changes
     *
     * @since 2.1.0
     * @param string $old_value Old URL
     * @param string $new_value New URL
     * @return void
     */
    public function track_home_url_change($old_value, $new_value) {
        if ($old_value !== $new_value) {
            $this->logging_service->log_event('home_url_changed', 'critical', array(
                'old_url' => $old_value,
                'new_url' => $new_value,
            ), 'system');
        }
    }
}

// Initialize event tracker
VMPFence_Event_Tracker::get_instance();
