<?php
/**
 * Spec for the ppok/abilities aggregator.
 *
 * @package Ppok\AIToolkit\Tests
 * @license GPL-2.0-or-later
 */

namespace Ppok\AIToolkit\Tests;

use Ppok\AIToolkit\Abilities\Abilities_List;
use Ppok\AIToolkit\Abilities\Ability_Registrar;
use Ppok\AIToolkit\Abilities\Post_Get_Blocks;
use Ppok\AIToolkit\Abilities\Post_List;
use Ppok\AIToolkit\Abilities\Rest_Call;
use Ppok\AIToolkit\Abilities\System_Ping;

class Test_Abilities_List extends \WP_UnitTestCase {

	public function test_slug_constant(): void {
		$this->assertSame( 'ppok/abilities', Abilities_List::SLUG );
	}

	public function test_descriptor_marks_read_only_and_mcp_public(): void {
		$d = Abilities_List::descriptor();
		$this->assertFalse( $d['meta']['ppok']['write'], 'Aggregator must be read-only.' );
		$this->assertTrue( $d['meta']['mcp']['public'], 'Aggregator must be exposed to MCP at registration time.' );
	}

	public function test_permission_callback_requires_logged_in(): void {
		wp_set_current_user( 0 );
		$this->assertFalse( Abilities_List::permission_callback() );

		$subscriber = self::factory()->user->create( array( 'role' => 'subscriber' ) );
		wp_set_current_user( $subscriber );
		$this->assertTrue( Abilities_List::permission_callback(), 'Any role with read cap (incl. subscriber) may discover abilities.' );
	}

	public function test_execute_returns_one_entry_per_registered_ability(): void {
		$result = Abilities_List::execute_callback();
		$this->assertArrayHasKey( 'abilities', $result );

		$slugs = array_column( $result['abilities'], 'name' );
		foreach ( array( System_Ping::SLUG, Rest_Call::SLUG, Post_List::SLUG, Post_Get_Blocks::SLUG, Abilities_List::SLUG ) as $expected ) {
			$this->assertContains( $expected, $slugs, "Aggregator missing slug: {$expected}" );
		}
		$this->assertCount( count( Ability_Registrar::abilities() ), $result['abilities'] );
	}

	public function test_each_entry_has_required_keys(): void {
		$result = Abilities_List::execute_callback();
		foreach ( $result['abilities'] as $entry ) {
			foreach ( array( 'name', 'title', 'description', 'input_schema', 'output_schema' ) as $key ) {
				$this->assertArrayHasKey( $key, $entry, "Aggregator entry missing key: {$key} for {$entry['name']}" );
			}
		}
	}

	public function test_rest_call_entry_carries_example_payload(): void {
		$result = Abilities_List::execute_callback();
		$entry  = $this->find_entry( $result['abilities'], Rest_Call::SLUG );
		$this->assertNotNull( $entry );
		$this->assertArrayHasKey( 'example', $entry );
		$this->assertSame( 'GET', $entry['example']['method'] );
		$this->assertArrayHasKey( 'reason', $entry['example'] );
	}

	private function find_entry( array $entries, string $slug ): ?array {
		foreach ( $entries as $entry ) {
			if ( $entry['name'] === $slug ) {
				return $entry;
			}
		}
		return null;
	}
}
