<?php
/**
 * Spec for Event_Logger payload size cap.
 *
 * A multi-megabyte input_args (e.g. a large block tree) must not be
 * stored verbatim into the LONGTEXT payload column — the activity viewer
 * would have to read megabytes per row to render the page. Past the cap
 * we keep only a stub that names the original size and dropped keys.
 *
 * @package Ppok\AIToolkit\Tests
 * @license GPL-2.0-or-later
 */

namespace Ppok\AIToolkit\Tests;

use Ppok\AIToolkit\Event_Logger;
use Ppok\AIToolkit\Request_Context;

class Test_Event_Logger_Payload_Cap extends \WP_UnitTestCase {

	protected function setUp(): void {
		parent::setUp();
		Event_Logger::install_schema();
	}

	public function test_small_payload_is_stored_verbatim(): void {
		$logger = new Event_Logger( new Request_Context() );
		$row_id = $logger->record(
			array(
				'ability_slug' => 'ppok/rest-call',
				'result'       => 'ok',
				'payload'      => array( 'input_args' => array( 'method' => 'GET', 'path' => '/wp/v2/posts' ) ),
			)
		);
		$this->assertGreaterThan( 0, $row_id );

		global $wpdb;
		$row = $wpdb->get_row( $wpdb->prepare( 'SELECT payload FROM ' . Event_Logger::table_name() . ' WHERE id = %d', $row_id ), ARRAY_A );
		$decoded = json_decode( (string) $row['payload'], true );
		$this->assertSame( 'GET', $decoded['input_args']['method'] );
		$this->assertArrayNotHasKey( '_truncated', $decoded );
	}

	public function test_oversize_payload_is_replaced_with_stub(): void {
		// Force a tight cap so we can trigger truncation without a real
		// multi-MB fixture.
		add_filter(
			'ppok_ai_toolkit_event_payload_max_bytes',
			static function () {
				return 512;
			}
		);

		$logger = new Event_Logger( new Request_Context() );
		$row_id = $logger->record(
			array(
				'ability_slug' => 'ppok/set-post-blocks',
				'result'       => 'ok',
				'payload'      => array(
					'input_args' => array(
						'post_id' => 1,
						'blocks'  => array( 'a' => str_repeat( 'x', 4096 ) ),
					),
					'diff'       => array( 'before' => str_repeat( 'y', 4096 ) ),
				),
			)
		);

		remove_all_filters( 'ppok_ai_toolkit_event_payload_max_bytes' );

		global $wpdb;
		$row     = $wpdb->get_row( $wpdb->prepare( 'SELECT payload FROM ' . Event_Logger::table_name() . ' WHERE id = %d', $row_id ), ARRAY_A );
		$decoded = json_decode( (string) $row['payload'], true );

		$this->assertTrue( $decoded['_truncated'] );
		$this->assertSame( 512, $decoded['_limit'] );
		$this->assertGreaterThan( 512, $decoded['_original_size'] );
		$this->assertEqualsCanonicalizing( array( 'input_args', 'diff' ), $decoded['_dropped_keys'] );
		// Stub itself must fit under the cap.
		$this->assertLessThanOrEqual( 512, strlen( (string) $row['payload'] ) );
	}
}
