<?php
/**
 * VmpFence WAF Failures Sync Module
 *
 * Syncs records from wp_vmpfence_waf_failures to the backend
 * via POST /api/v1/firewall/waf-failures/batch (payload key: 'failures')
 *
 * @package    VMPFence
 * @subpackage Includes\Sync
 * @since      2.2.4
 */

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

class VmpFence_WAF_Failures_Sync extends VmpFence_Base_Sync {

    /**
     * Records per API call
     * @var int
     */
    protected $batch_size = 50;

    /**
     * Constructor
     *
     * @since 2.2.4
     */
    public function __construct() {
        global $wpdb;
        $this->table_name = $wpdb->prefix . 'vmpfence_waf_failures';
        parent::__construct();
    }

    /**
     * Get the API client method name for this sync module.
     *
     * @since 2.2.4
     * @return string
     */
    protected function get_endpoint_method(): string {
        return 'sync_waf_failures_batch';
    }

    /**
     * Transform a database row into the API payload format.
     *
     * DB Audit (Feb 16, 2026):
     * - Removed `fail_count` and `blocked_until` — do NOT exist on WAFFailure model
     *   (they belong to LockoutState)
     * - Added `error_message` which is NOT NULL on server
     * - Changed `request_uri` → `request_url` to match server field
     * - `IP` is stored as varbinary(16) — converted via format_ip()
     * - `ctime` is double(17,6) Unix timestamp — converted via date()
     *
     * Column Audit (Feb 15, 2026 — Bugfix):
     * - No `error_message` column in plugin table — use `reason` (best available)
     * - `reason` is used for both `failure_type` category and `error_message` detail
     *
     * @since 2.2.4
     * @param array $row Database row
     * @return array Transformed record
     */
    protected function transform_record(array $row): array {
        $reason = $row['reason'] ?? 'unknown';

        return array(
            'plugin_event_id' => (int) $row['id'],
            'ip_address'      => isset($row['IP']) ? $this->format_ip($row['IP']) : null,
            'failure_type'    => $reason,
            'rule_id'         => null,
            'error_message'   => $reason,
            'request_url'     => null,
            'occurred_at'     => isset($row['ctime']) ? gmdate('Y-m-d\TH:i:s\Z', (int) $row['ctime']) : current_time('c'),
        );
    }
}
