<?php
/**
 * Ability: wp-agent/list-themes
 *
 * Read-only. Listet installierte Themes mit Version und Aktiv-Status.
 *
 * Definiert zusätzlich wpagent_perm_switch_themes(): helpers.php gehört zu
 * den geteilten Dateien dieser Welle und wird hier bewusst nicht angefasst
 * (das macht die Integrationsphase). Die switch_themes-Capability-Prüfung
 * lebt deshalb vorläufig hier, im Muster der übrigen wpagent_perm_*-
 * Funktionen aus helpers.php; sie wird von list-themes UND switch-theme
 * genutzt (siehe switch-theme.php) und sollte bei der Integration nach
 * helpers.php wandern, damit alle wpagent_perm_*-Funktionen an einem Ort
 * stehen.
 *
 * @package WPAgentCompanion
 */

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

/**
 * Permission callback: der Aufrufer muss Themes wechseln dürfen.
 *
 * list-themes und switch-theme sind Geschwister-Abilities (lesen/schreiben
 * desselben Themes-Bereichs) und teilen deshalb dieselbe Capability, analog
 * dazu, wie list-plugins dieselbe activate_plugins-Capability wie
 * activate-plugin/deactivate-plugin nutzt. Wie edit_themes/activate_plugins
 * bekommt ein Editor switch_themes nicht per Default; siehe die
 * wpagent_perm_edit_themes-Doku in helpers.php.
 *
 * @param mixed $input Unused ability input.
 * @return bool
 */
function wpagent_perm_switch_themes( $input = null ): bool {
	return current_user_can( 'switch_themes' );
}

function wpagent_ability_list_themes(): array {
	return array(
		'label'               => __( 'Themes auflisten', 'wp-agent-companion' ),
		'description'         => __( 'Listet installierte Themes mit Stylesheet-Ordnername, Name, Version und Aktiv-Status.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'additionalProperties' => false,
			'properties'           => array(
				'items' => array(
					'type'     => 'array',
					'maxItems' => 100,
					'items' => array(
						'type'                 => 'object',
						'additionalProperties' => false,
						'properties'           => array(
							'stylesheet' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 128, 'pattern' => '^[A-Za-z0-9][A-Za-z0-9._-]*$' ),
							'name'       => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 200 ),
							'version'    => array( 'type' => 'string', 'maxLength' => 100 ),
							'active'     => array( 'type' => 'boolean' ),
						),
						'required'             => array( 'stylesheet', 'name', 'version', 'active' ),
					),
				),
				'total' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => 100 ),
			),
			'required'   => array( 'items', 'total' ),
		),
		'execute_callback'    => 'wpagent_exec_list_themes',
		'permission_callback' => 'wpagent_perm_switch_themes',
		'meta'                => array(
			'show_in_rest' => true,
			'annotations'  => array(
				'readonly'    => true,
				'destructive' => false,
				'idempotent'  => true,
			),
		),
	);
}

/**
 * @param mixed $input Unused; die Ability nimmt keine Parameter entgegen.
 * @return array|WP_Error
 */
function wpagent_exec_list_themes( $input = null ) {
	$input_valid = wpagent_builder_read_empty_object_input( $input );
	if ( is_wp_error( $input_valid ) ) {
		return $input_valid;
	}
	$active_stylesheet = get_stylesheet();

	$items = array();
	foreach ( wp_get_themes() as $stylesheet => $theme ) {
		$items[] = array(
			'stylesheet' => (string) $stylesheet,
			'name'       => (string) $theme->get( 'Name' ),
			'version'    => (string) $theme->get( 'Version' ),
			'active'     => ( (string) $stylesheet === $active_stylesheet ),
		);
	}

	$result = array(
		'items' => $items,
		'total' => count( $items ),
	);
	$output_valid = wpagent_list_themes_validate_output( $result );
	return is_wp_error( $output_valid ) ? $output_valid : $result;
}

/** @return true|WP_Error */
function wpagent_list_themes_validate_output( array $result ) {
	if ( array( 'items', 'total' ) !== array_keys( $result ) || ! is_array( $result['items'] ) || count( $result['items'] ) > 100 || ! is_int( $result['total'] ) || $result['total'] !== count( $result['items'] ) ) {
		return wpagent_builder_read_invalid_output();
	}
	foreach ( $result['items'] as $item ) {
		if ( ! is_array( $item ) || array( 'stylesheet', 'name', 'version', 'active' ) !== array_keys( $item )
			|| ! wpagent_builder_read_valid_text( $item['stylesheet'], 1, 128, '/^[A-Za-z0-9][A-Za-z0-9._-]*$/' )
			|| ! wpagent_builder_read_valid_text( $item['name'], 1, 200 ) || ! wpagent_builder_read_valid_text( $item['version'], 0, 100 ) || ! is_bool( $item['active'] ) ) {
			return wpagent_builder_read_invalid_output();
		}
	}
	return true;
}
