<?php
/**
 * Tool Manager.
 *
 * Handles the registration, retrieval, and management of agent tools.
 * Provides a central registry for all available tools and their configurations.
 *
 * @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://maximum.software/
 *
 * 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' ) ) {
	return;
}

/**
 * Tool_Manager class.
 */
class Tool_Manager extends Manager {
	/**
	 * Registered tools
	 * @var        array
	 */
	private $tools = array();

	/**
	 * Mapping of tool IDs to tool classes
	 * @var        array
	 */
	private $tool_mapping = array(
		// Core tools
		'list_all_tools'               => 'List_All_Tools_Tool',
		'import_tools'                 => 'Import_Tools_Tool',
		'unimport_tools'               => 'Unimport_Tools_Tool',
		'terminate'                    => 'Terminate_Tool',
		'continue'                     => 'Continue_Tool',
		// Content tools
		'search_content'               => 'Search_Content_Tool',
		'create_post'                  => 'Create_Post_Tool',
		'create_page'                  => 'Create_Page_Tool',
		'update_page'                  => 'Update_Page_Tool',
		'delete_page'                  => 'Delete_Page_Tool',
		'update_post'                  => 'Update_Post_Tool',
		'delete_post'                  => 'Delete_Post_Tool',
		'get_post_details'             => 'Get_Post_Details_Tool',
		'get_page_details'             => 'Get_Page_Details_Tool',
		'list_posts'                   => 'List_Posts_Tool',
		'list_pages'                   => 'List_Pages_Tool',
		// Post Meta tools
		'list_post_meta'               => 'List_Post_Meta_Tool',
		'get_post_meta'                => 'Get_Post_Meta_Tool',
		'create_post_meta'             => 'Create_Post_Meta_Tool',
		'update_post_meta'             => 'Update_Post_Meta_Tool',
		'delete_post_meta'             => 'Delete_Post_Meta_Tool',
		// Comment tools
		'list_comments'                => 'List_Comments_Tool',
		'get_comment_details'          => 'Get_Comment_Details_Tool',
		'create_comment'               => 'Create_Comment_Tool',
		'update_comment'               => 'Update_Comment_Tool',
		'delete_comment'               => 'Delete_Comment_Tool',
		// Category tools
		'list_categories'              => 'List_Categories_Tool',
		'get_category_details'         => 'Get_Category_Details_Tool',
		'create_category'              => 'Create_Category_Tool',
		'update_category'              => 'Update_Category_Tool',
		'delete_category'              => 'Delete_Category_Tool',
		// Tag tools
		'list_tags'                    => 'List_Tags_Tool',
		'get_tag_details'              => 'Get_Tag_Details_Tool',
		'create_tag'                   => 'Create_Tag_Tool',
		'update_tag'                   => 'Update_Tag_Tool',
		'delete_tag'                   => 'Delete_Tag_Tool',
		// Media tools
		'list_media'                   => 'List_Media_Tool',
		'get_media_details'            => 'Get_Media_Details_Tool',
		'upload_media'                 => 'Upload_Media_Tool',
		'update_media'                 => 'Update_Media_Tool',
		'delete_media'                 => 'Delete_Media_Tool',
		'download_media'               => 'Download_Media_Tool',
		// User tools
		'list_users'                   => 'List_Users_Tool',
		'get_user_details'             => 'Get_User_Details_Tool',
		'get_current_user'             => 'Get_Current_User_Tool',
		'create_user'                  => 'Create_User_Tool',
		'update_user'                  => 'Update_User_Tool',
		'delete_user'                  => 'Delete_User_Tool',
		'send_password_reset'          => 'Send_Password_Reset_Tool',
		// Plugin tools
		'list_installed_plugins'       => 'List_Installed_Plugins_Tool',
		'list_active_plugins'          => 'List_Active_Plugins_Tool',
		'get_plugin_details'           => 'Get_Plugin_Details_Tool',
		'search_plugins'               => 'Search_Plugins_Tool',
		'install_plugin'               => 'Install_Plugin_Tool',
		'uninstall_plugin'             => 'Uninstall_Plugin_Tool',
		'update_plugins'               => 'Update_Plugins_Tool',
		'activate_plugin'              => 'Activate_Plugin_Tool',
		'deactivate_plugin'            => 'Deactivate_Plugin_Tool',
		// Plugin creation/editing tools
		'create_plugin'                => 'Create_Plugin_Tool',
		'list_plugin_files'            => 'List_Plugin_Files_Tool',
		'read_plugin_file'             => 'Read_Plugin_File_Tool',
		'write_plugin_file'            => 'Write_Plugin_File_Tool',
		'delete_plugin_file'           => 'Delete_Plugin_File_Tool',
		// Theme tools
		'list_installed_themes'        => 'List_Installed_Themes_Tool',
		'get_active_theme'             => 'Get_Active_Theme_Tool',
		'get_theme_details'            => 'Get_Theme_Details_Tool',
		'search_themes'                => 'Search_Themes_Tool',
		'install_theme'                => 'Install_Theme_Tool',
		'uninstall_theme'              => 'Uninstall_Theme_Tool',
		'update_themes'                => 'Update_Themes_Tool',
		'activate_theme'               => 'Activate_Theme_Tool',
		// Theme creation/editing tools
		'create_theme'                 => 'Create_Theme_Tool',
		'list_theme_files'             => 'List_Theme_Files_Tool',
		'read_theme_file'              => 'Read_Theme_File_Tool',
		'write_theme_file'             => 'Write_Theme_File_Tool',
		'delete_theme_file'            => 'Delete_Theme_File_Tool',
		// Debug log tools
		'get_debug_log_info'           => 'Get_Debug_Log_Info_Tool',
		'read_debug_log_file'          => 'Read_Debug_Log_File_Tool',
		// Options tools
		'list_options'                 => 'List_Options_Tool',
		'get_option_value'             => 'Get_Option_Value_Tool',
		'update_option'                => 'Update_Option_Tool',
		'delete_option'                => 'Delete_Option_Tool',
		// Site tools
		'get_site_info'                => 'Get_Site_Info_Tool',
		'get_site_health'              => 'Get_Site_Health_Tool',
		'list_available_updates'       => 'List_Available_Updates_Tool',
		'update_core'                  => 'Update_Core_Tool',
		// Web tools
		'send_email'                   => 'Send_Email_Tool',
		'fetch_url'                    => 'Fetch_Url_Tool',
		'download_file'                => 'Download_File_Tool',
		// Config tools
		'configure_llm_provider'       => 'Configure_LLM_Provider_Tool',
		'get_chat_model'               => 'Get_Chat_Model_Tool',
		'get_embeddings_model'         => 'Get_Embeddings_Model_Tool',
		'list_chat_models'             => 'List_Chat_Models_Tool',
		'list_embeddings_models'       => 'List_Embeddings_Models_Tool',
		'change_chat_model'            => 'Change_Chat_Model_Tool',
		'change_embeddings_model'      => 'Change_Embeddings_Model_Tool',
		'sync_embeddings'              => 'Sync_Embeddings_Tool',
		'change_chat_position'         => 'Change_Chat_Position_Tool',
		// Role and capability tools
		'list_roles'                   => 'List_Roles_Tool',
		'get_role_details'             => 'Get_Role_Details_Tool',
		'list_capabilities'            => 'List_Capabilities_Tool',
		'check_user_capability'        => 'Check_User_Capability_Tool',
		'add_role'                     => 'Add_Role_Tool',
		'remove_role'                  => 'Remove_Role_Tool',
		'clone_role'                   => 'Clone_Role_Tool',
		'add_capability_to_role'       => 'Add_Capability_To_Role_Tool',
		'remove_capability_from_role'  => 'Remove_Capability_From_Role_Tool',
		'grant_user_capability'        => 'Grant_User_Capability_Tool',
		'revoke_user_capability'       => 'Revoke_User_Capability_Tool',
		// System tools
		'calculate_php'                => 'Calculate_PHP_Tool',
		'execute_php'                  => 'Execute_PHP_Tool',
		'execute_cli'                  => 'Execute_CLI_Tool',
		'read_file'                    => 'Read_File_Tool',
		'write_file'                   => 'Write_File_Tool',
		'list_files'                   => 'List_Files_Tool',
		'delete_file'                  => 'Delete_File_Tool',
		'db_query'                     => 'DB_Query_Tool',
		'db_execute'                   => 'DB_Execute_Tool',
		// Menu tools
		'list_menus'                   => 'List_Menus_Tool',
		'create_menu'                  => 'Create_Menu_Tool',
		'delete_menu'                  => 'Delete_Menu_Tool',
		'get_menu_details'             => 'Get_Menu_Details_Tool',
		'add_menu_item'                => 'Add_Menu_Item_Tool',
		'update_menu_item'             => 'Update_Menu_Item_Tool',
		'delete_menu_item'             => 'Delete_Menu_Item_Tool',
		'list_menu_locations'          => 'List_Menu_Locations_Tool',
		'assign_menu_to_location'      => 'Assign_Menu_To_Location_Tool',
		'unassign_menu_from_location'  => 'Unassign_Menu_From_Location_Tool',
		// Cron tools
		'list_cron_events'             => 'WP_Cron_Event_List_Tool',
		'get_cron_event_details'       => 'WP_Cron_Event_Details_Tool',
		'list_cron_schedules'          => 'WP_Cron_Schedule_List_Tool',
		'schedule_cron_event'          => 'WP_Cron_Event_Schedule_Tool',
		'unschedule_cron_event'        => 'WP_Cron_Event_Unschedule_Tool',
		'run_cron'                     => 'WP_Cron_Run_Tool',
		'cron_event_exists'            => 'WP_Cron_Event_Exists_Tool',
		// Action Scheduler tools
		'list_scheduled_actions'       => 'Action_Scheduler_List_Tool',
		'get_scheduled_action_details' => 'Action_Scheduler_Details_Tool',
		'schedule_action'              => 'Action_Scheduler_Schedule_Tool',
		'cancel_scheduled_action'      => 'Action_Scheduler_Cancel_Tool',
		'run_scheduled_action'         => 'Action_Scheduler_Run_Tool',
		'search_scheduled_actions'     => 'Action_Scheduler_Search_Tool',
		// Shortcode tools
		'list_shortcodes'              => 'List_Shortcodes_Tool',
		'get_shortcode_details'        => 'Get_Shortcode_Details_Tool',
		'render_shortcode'             => 'Render_Shortcode_Tool',
		// Post type tools
		'list_post_types'              => 'List_Post_Types_Tool',
		'get_post_type_details'        => 'Get_Post_Type_Details_Tool',
		// Custom post type tools
		'list_custom_posts'            => 'List_Custom_Posts_Tool',
		'get_custom_post'              => 'Get_Custom_Post_Tool',
		'create_custom_post'           => 'Create_Custom_Post_Tool',
		'update_custom_post'           => 'Update_Custom_Post_Tool',
		'delete_custom_post'           => 'Delete_Custom_Post_Tool',
		// Taxonomy tools
		'list_taxonomies'              => 'List_Taxonomies_Tool',
		'get_taxonomy_details'         => 'Get_Taxonomy_Details_Tool',
		'list_terms'                   => 'List_Terms_Tool',
		'get_term_details'             => 'Get_Term_Details_Tool',
		'create_term'                  => 'Create_Term_Tool',
		'update_term'                  => 'Update_Term_Tool',
		'delete_term'                  => 'Delete_Term_Tool',
		'term_exists'                  => 'Term_Exists_Tool',
	);

	/**
	 * Cached always-imported tools
	 * @var        array|null
	 */
	private $always_imported_tools_cache = null;

	/**
	 * Constructor - initializes the manager
	 * @since     1.0.0
	 */
	protected function __construct() {
		// Register built-in tools
		$this->register_built_in_tools();

		// Call parent constructor with option suffix
		parent::__construct( 'tool_settings' );
	}

	/**
	 * Get default configuration
	 *
	 * Returns tool settings with default values based on each tool's
	 * default enabled status.
	 *
	 * @return array Default configuration
	 * @since     1.0.0
	 */
	protected function get_default_config() {
		// Initialize with empty tools configuration
		$tools_config = array();

		// Get default enabled status from each tool instance
		foreach ( $this->tools as $tool_id => $tool ) {
			$tools_config[ $tool_id ] = array(
				'enabled' => $tool->get_default_enabled_status(),
			);
		}

		// Return configuration with tools array
		return array(
			'tools' => $tools_config,
		);
	}

	/**
	 * Register built-in tools provided by the plugin
	 */
	private function register_built_in_tools() {
		// Register each tool if its class exists
		foreach ( $this->tool_mapping as $class_name ) {
			$full_class_name = '\\Agenistrator\\' . $class_name;
			if ( class_exists( $full_class_name ) ) {
				$tool = new $full_class_name();
				$this->register_tool( $tool );
			}
		}
	}

	/**
	 * Register a tool
	 *
	 * @param      Tool $tool The tool to register
	 * @return     bool True if registration succeeded, false otherwise
	 * @since     1.0.0
	 */
	public function register_tool( $tool ) {
		if ( ! ( $tool instanceof Tool ) ) {
			return false;
		}

		$id = $tool->get_id();
		if ( empty( $id ) ) {
			return false;
		}

		$this->always_imported_tools_cache = null;
		$this->tools[ $id ]                = $tool;
		return true;
	}

	/**
	 * Unregister a tool
	 *
	 * @param      string $name The name of the tool to unregister
	 * @return     bool True if unregistration succeeded, false otherwise
	 * @since     1.0.0
	 */
	public function unregister_tool( $name ) {
		if ( isset( $this->tools[ $name ] ) ) {
			$this->always_imported_tools_cache = null;
			unset( $this->tools[ $name ] );
			return true;
		}
		return false;
	}

	/**
	 * Get all registered tools
	 *
	 * @param      bool $only_enabled Whether to return only enabled tools
	 * @return     array Array of registered tools
	 * @since     1.0.0
	 */
	public function get_tools( $only_enabled = false ) {
		if ( ! $only_enabled ) {
			return $this->tools;
		}

		$enabled_tools = array();
		foreach ( $this->tools as $name => $tool ) {
			if ( $this->is_tool_enabled( $name ) ) {
				$enabled_tools[ $name ] = $tool;
			}
		}

		return $enabled_tools;
	}

	/**
	 * Get a specific tool by name
	 *
	 * @param      string $name The name of the tool to get
	 * @return     Tool|null The tool, or null if not found
	 * @since     1.0.0
	 */
	public function get_tool( $name ) {
		return $this->tools[ $name ] ?? null;
	}

	/**
	 * Get tools that are always imported (core tools)
	 *
	 * @return     array Array of tools that are always imported
	 * @since     1.0.0
	 */
	public function get_always_imported_tools() {
		if ( null !== $this->always_imported_tools_cache ) {
			return $this->always_imported_tools_cache;
		}

		$result = array();
		foreach ( $this->tools as $id => $tool ) {
			if ( $tool->is_always_imported() ) {
				$result[ $id ] = $tool;
			}
		}

		$this->always_imported_tools_cache = $result;
		return $result;
	}

	/**
	 * Get tool settings
	 *
	 * @return     array The tool settings
	 * @since     1.0.0
	 */
	public function get_tool_settings() {
		// Ensure all registered tools have settings
		foreach ( $this->tools as $tool_id => $tool ) {
			if ( ! $this->get_config( array( 'tools', $tool_id ) ) ) {
				$this->set_config_and_save(
					array( 'tools', $tool_id ),
					array(
						'enabled' => $tool->get_default_enabled_status(),
					)
				);
			}
		}

		return $this->get_config( array( 'tools' ), array() );
	}

	/**
	 * Check if a tool is enabled
	 *
	 * Always-enabled tools return true regardless of settings.
	 *
	 * @param      string $tool_id The ID of the tool to check
	 * @return     bool True if the tool is enabled, false otherwise
	 * @since     1.0.0
	 */
	public function is_tool_enabled( $tool_id ) {
		$tool = $this->get_tool( $tool_id );
		if ( ! $tool ) {
			return false;
		}

		// Always-enabled tools cannot be disabled
		if ( $tool->is_always_enabled() ) {
			return true;
		}

		$enabled = $this->get_config( array( 'tools', $tool_id, 'enabled' ) );
		if ( null !== $enabled ) {
			return $enabled;
		}

		return $tool->get_default_enabled_status();
	}

	/**
	 * Set a tool's enabled status
	 *
	 * Cannot disable always-enabled tools.
	 *
	 * @param      string $tool_id The ID of the tool to update
	 * @param      bool $enabled True to enable, false to disable
	 * @return     bool True if the update succeeded, false otherwise
	 * @throws     \Exception If trying to disable an always-enabled tool
	 * @since     1.0.0
	 */
	public function set_tool_enabled( $tool_id, $enabled ) {
		$tool = $this->get_tool( $tool_id );
		if ( ! $tool ) {
			// phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception messages are not HTML output
			throw new \Exception( __( 'Tool not found.', 'agenistrator' ) );
		}

		// Prevent disabling always-enabled tools
		if ( $tool->is_always_enabled() && ! $enabled ) {
			// phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception messages are not HTML output
			throw new \Exception( __( 'This tool cannot be disabled.', 'agenistrator' ) );
		}

		// Update enabled status and save
		return $this->set_config_and_save( array( 'tools', $tool_id, 'enabled' ), $enabled );
	}
}
