<?php
/**
 * Sensor Collector — Pfad B (Threat-Intelligence Network).
 *
 * Subscribes to the plugin's internal event stream and turns network-relevant
 * events into queued SensorEvents (RFC §3.1 Collector.php). It is the only
 * place the per-site layers (WAF / Anomaly / Bruteforce / Incident Commander)
 * touch the sensor pipeline — they keep firing `shieldforge_event_emitted`
 * exactly as before, oblivious to whether a sensor is attached.
 *
 * Collect + enqueue locally, then Transport.php ships the queue on. The flow is:
 *   event_emitted → consent gate → Privacy::to_sensor_event() → Batcher::enqueue()
 *                 → Batcher::record_audit() (transparency) → Transport::flush()
 *
 * @package Brainwerk Security Suite
 */

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

class Shieldforge_Sensor_Collector {

    public static function register( $loader ) {
        // 3 args: raw payload, built internal event, local event id.
        $loader->add_action( 'shieldforge_event_emitted', __CLASS__, 'on_event', 20, 3 );
    }

    /**
     * @param array  $payload         Raw producer payload (may contain raw IP/UA).
     * @param array  $internal_event  The sf1$-hashed local event.
     * @param string $event_id        Local event id (unused here; SensorEvent gets its own uuid).
     */
    public static function on_event( $payload, $internal_event, $event_id = '' ) {
        // Strict opt-in: with consent off, the sensor produces and stores
        // nothing at all (not even a queued item).
        if ( ! Shieldforge_Sensor_Privacy::consent_given() ) {
            return;
        }
        if ( ! is_array( $payload ) || ! is_array( $internal_event ) ) {
            return;
        }

        $sensor_event = Shieldforge_Sensor_Privacy::to_sensor_event( $payload, $internal_event );
        if ( null === $sensor_event ) {
            return; // not network-relevant
        }

        // Per-event feed opt-in defaults from the site setting; transport in
        // Phase 1 will only upload events whose flag is true. Kept as queue
        // metadata, NOT inside the SensorEvent (its wire schema forbids it).
        $meta = array( 'share_with_feed' => Shieldforge_Sensor_Privacy::share_with_feed_default() );

        if ( Shieldforge_Sensor_Batcher::enqueue( $sensor_event, $meta ) ) {
            Shieldforge_Sensor_Batcher::record_audit(
                Shieldforge_Sensor_Privacy::describe_for_audit( $sensor_event )
            );
        }
    }
}
