<?php
/**
 * List Available Updates Tool.
 *
 * Lists all available updates for plugins, themes, and WordPress core.
 * Uses WordPress update transients for cached update information.
 *
 * @package   Agenistrator
 * @since     1.0.0
 * @author    Alex Ruban <alex@maximum.guru>
 * @author    Maximum Software Inc <contact@maximum.software>
 * @license   GPL-3.0-only
 * @link      https://agenistrator.com/
 *
 * SPDX-FileCopyrightText: 2025-2026 Alex Ruban <alex@maximum.guru>
 * SPDX-FileCopyrightText: 2025-2026 Maximum Software Inc <contact@maximum.software>
 * SPDX-License-Identifier: GPL-3.0-only
 */

namespace Agenistrator;

// Direct access prevention
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * List_Available_Updates_Tool class.
 */
class List_Available_Updates_Tool extends Tool {

	/**
	 * Get the tool ID.
	 *
	 * @return string The tool ID.
	 * @since     1.0.0
	 */
	public function get_id() {
		return 'list_available_updates';
	}

	/**
	 * Get the tool name.
	 *
	 * @return string The tool name.
	 * @since     1.0.0
	 */
	public function get_name() {
		return __( 'List Available Updates', 'agenistrator' );
	}

	/**
	 * Get the tool description.
	 *
	 * @return string The tool description.
	 * @since     1.0.0
	 */
	public function get_description() {
		return 'List all available updates for WordPress core, plugins, and themes. Returns information about pending updates including current and new versions.';
	}

	/**
	 * Get the parameters schema for this tool.
	 *
	 * @return array Parameters schema in JSON Schema format.
	 * @since     1.0.0
	 */
	public function get_parameters() {
		return array(
			'type'       => 'object',
			'properties' => array(
				'type' => array(
					'type'        => 'string',
					'description' => 'Filter by update type: "all", "plugins", "themes", or "core"',
					'enum'        => array( 'all', 'plugins', 'themes', 'core' ),
					'default'     => 'all',
				),
			),
			'required'   => array(),
		);
	}

	/**
	 * Check if the current user can execute this tool.
	 *
	 * @return bool True if the current user has permission.
	 * @since     1.0.0
	 */
	public function current_user_can_execute() {
		return current_user_can( 'update_plugins' ) || current_user_can( 'update_themes' ) || current_user_can( 'update_core' );
	}

	/**
	 * Check if this tool is read-only.
	 *
	 * @return bool True if the tool only reads data.
	 * @since     1.0.0
	 */
	public function is_read_only() {
		return true;
	}

	/**
	 * Get the default enabled status for this tool.
	 *
	 * @return bool True if enabled by default, false otherwise.
	 * @since     1.0.0
	 */
	public function get_default_enabled_status() {
		return true;
	}

	/**
	 * Execute the tool with the given arguments.
	 *
	 * @param array $args The tool arguments.
	 *
	 * @return array The tool execution result.
	 * @since     1.0.0
	 */
	protected function execute( $args ) {
		// Force WordPress to check for updates
		wp_update_plugins();
		wp_update_themes();
		wp_version_check();

		$type    = $args['type'] ?? 'all';
		$updates = array();

		// Get plugin updates
		if ( 'all' === $type || 'plugins' === $type ) {
			$updates['plugins'] = $this->get_plugin_updates();
		}

		// Get theme updates
		if ( 'all' === $type || 'themes' === $type ) {
			$updates['themes'] = $this->get_theme_updates();
		}

		// Get core updates
		if ( 'all' === $type || 'core' === $type ) {
			$updates['core'] = $this->get_core_updates();
		}

		// Calculate summary
		$summary                  = array(
			'plugins_count'  => count( $updates['plugins'] ?? array() ),
			'themes_count'   => count( $updates['themes'] ?? array() ),
			'core_available' => ! empty( $updates['core'] ?? null ),
			'total_updates'  => 0,
		);
		$summary['total_updates'] = $summary['plugins_count'] + $summary['themes_count'] + ( $summary['core_available'] ? 1 : 0 );

		return $this->success_response(
			'Available updates retrieved',
			array(
				'summary' => $summary,
				'updates' => $updates,
			)
		);
	}

	/**
	 * Get available plugin updates
	 */
	private function get_plugin_updates() {
		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		$update_plugins = get_site_transient( 'update_plugins' );
		$plugins        = array();

		if ( ! empty( $update_plugins->response ) ) {
			$all_plugins = get_plugins();

			foreach ( $update_plugins->response as $plugin_file => $update_info ) {
				$plugin_data = $all_plugins[ $plugin_file ] ?? array();

				$plugins[] = array(
					'file'            => $plugin_file,
					'slug'            => $update_info->slug ?? dirname( $plugin_file ),
					'name'            => $plugin_data['Name'] ?? $plugin_file,
					'current_version' => $plugin_data['Version'] ?? 'unknown',
					'new_version'     => $update_info->new_version,
					'url'             => $update_info->url ?? null,
					'package'         => $update_info->package ?? null,
					'requires_php'    => $update_info->requires_php ?? null,
					'requires_wp'     => $update_info->requires ?? null,
					'tested_wp'       => $update_info->tested ?? null,
				);
			}
		}

		return $plugins;
	}

	/**
	 * Get available theme updates
	 */
	private function get_theme_updates() {
		$update_themes = get_site_transient( 'update_themes' );
		$themes        = array();

		if ( ! empty( $update_themes->response ) ) {
			foreach ( $update_themes->response as $theme_slug => $update_info ) {
				$theme = wp_get_theme( $theme_slug );

				$themes[] = array(
					'slug'            => $theme_slug,
					'name'            => $theme->exists() ? $theme->get( 'Name' ) : $theme_slug,
					'current_version' => $theme->exists() ? $theme->get( 'Version' ) : 'unknown',
					'new_version'     => $update_info['new_version'],
					'url'             => $update_info['url'] ?? null,
					'package'         => $update_info['package'] ?? null,
					'requires_php'    => $update_info['requires_php'] ?? null,
					'requires_wp'     => $update_info['requires'] ?? null,
				);
			}
		}

		return $themes;
	}

	/**
	 * Get available core updates
	 */
	private function get_core_updates() {
		$update_core = get_site_transient( 'update_core' );

		if ( empty( $update_core->updates ) ) {
			return null;
		}

		// Find the latest version update (not 'latest' which means current)
		foreach ( $update_core->updates as $update ) {
			if ( 'upgrade' === $update->response ) {
				return array(
					'current_version' => get_bloginfo( 'version' ),
					'new_version'     => $update->version,
					'locale'          => $update->locale,
					'php_version'     => $update->php_version ?? null,
					'mysql_version'   => $update->mysql_version ?? null,
					'package'         => $update->packages->full ?? null,
				);
			}
		}

		return null;
	}
}
