<?php
/**
 * Custom Class Autoloader.
 *
 * Handles automatic class loading using an explicit class-to-file mapping.
 * Uses a direct mapping approach rather than PSR-4 conventions for more
 * flexibility and explicit control over class locations.
 *
 * @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;
}

/**
 * Autoloader class.
 */
class Autoloader {
	/**
	 * The single instance of this class
	 * @var        Autoloader
	 */
	private static $instance = null;

	/**
	 * Plugin directory path
	 * @var        string
	 */
	private $plugin_dir;

	/**
	 * Class to file mapping
	 * @var        array
	 */
	private $class_map = array();

	/**
	 * Get the single instance of this class
	 *
	 * @return     Autoloader  The singleton instance
	 * @since     1.0.0
	 */
	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Private constructor to enforce singleton pattern
	 */
	private function __construct() {
		$this->plugin_dir = plugin_dir_path( __DIR__ );
		$this->initialize_class_map();
	}

	/**
	 * Initialize the explicit class to file mapping
	 *
	 * Creates a direct mapping between class names and their file paths,
	 * allowing for precise control over where each class is located.
	 */
	private function initialize_class_map() {
		// Core classes
		$this->class_map = array(
			// Admin classes
			'Admin'                            => 'admin/class-admin.php',
			'Settings'                         => 'admin/class-settings.php',
			'Chat'                             => 'admin/class-chat.php',
			'Ajax_Exception'                   => 'admin/class-ajax-exception.php',

			// Base types
			'Singleton'                        => 'includes/traits/trait-singleton.php',
			'Maintenance'                      => 'includes/interfaces/interface-maintenance.php',
			'Manager'                          => 'includes/abstract/class-manager.php',

			// Core includes
			'Main'                             => 'includes/class-main.php',
			'String_Utils'                     => 'includes/class-string-utils.php',
			'Chunk_Extractor'                  => 'includes/class-chunk-extractor.php',
			'Embeddings_Manager'               => 'includes/class-embeddings-manager.php',
			'Provider_Manager'                 => 'includes/class-provider-manager.php',
			'LLM_Manager'                      => 'includes/class-llm-manager.php',
			'Tool_Manager'                     => 'includes/class-tool-manager.php',
			'Chat_Log_Manager'                 => 'includes/class-chat-log-manager.php',
			'Thread_Manager'                   => 'includes/class-thread-manager.php',
			'Thread'                           => 'includes/class-thread.php',
			'Reporter'                         => 'includes/class-reporter.php',
			'Content_Guard'                    => 'includes/class-content-guard.php',
			'WordPress_Utils'                  => 'includes/class-wordpress-utils.php',
			'PHP_Utils'                        => 'includes/class-php-utils.php',

			// Tool classes
			'Tool'                             => 'includes/tools/class-tool.php',
			'Abstract_File_Reader_Tool'        => 'includes/tools/abstracts/class-abstract-file-reader-tool.php',
			'Abstract_File_Writer_Tool'        => 'includes/tools/abstracts/class-abstract-file-writer-tool.php',
			// Core tools
			'List_All_Tools_Tool'              => 'includes/tools/core/class-list-all-tools-tool.php',
			'Import_Tools_Tool'                => 'includes/tools/core/class-import-tools-tool.php',
			'Unimport_Tools_Tool'              => 'includes/tools/core/class-unimport-tools-tool.php',
			'Terminate_Tool'                   => 'includes/tools/core/class-terminate-tool.php',
			'Continue_Tool'                    => 'includes/tools/core/class-continue-tool.php',
			// Content tools
			'Search_Content_Tool'              => 'includes/tools/content/class-search-content-tool.php',
			'Create_Post_Tool'                 => 'includes/tools/content/class-create-post-tool.php',
			'Create_Page_Tool'                 => 'includes/tools/content/class-create-page-tool.php',
			'Update_Page_Tool'                 => 'includes/tools/content/class-update-page-tool.php',
			'Delete_Page_Tool'                 => 'includes/tools/content/class-delete-page-tool.php',
			'Update_Post_Tool'                 => 'includes/tools/content/class-update-post-tool.php',
			'Delete_Post_Tool'                 => 'includes/tools/content/class-delete-post-tool.php',
			'Get_Post_Details_Tool'            => 'includes/tools/content/class-get-post-details-tool.php',
			'Get_Page_Details_Tool'            => 'includes/tools/content/class-get-page-details-tool.php',
			'List_Posts_Tool'                  => 'includes/tools/content/class-list-posts-tool.php',
			'List_Pages_Tool'                  => 'includes/tools/content/class-list-pages-tool.php',
			// Post Meta tools
			'List_Post_Meta_Tool'              => 'includes/tools/content/class-list-post-meta-tool.php',
			'Get_Post_Meta_Tool'               => 'includes/tools/content/class-get-post-meta-tool.php',
			'Create_Post_Meta_Tool'            => 'includes/tools/content/class-create-post-meta-tool.php',
			'Update_Post_Meta_Tool'            => 'includes/tools/content/class-update-post-meta-tool.php',
			'Delete_Post_Meta_Tool'            => 'includes/tools/content/class-delete-post-meta-tool.php',
			// Comment tools
			'List_Comments_Tool'               => 'includes/tools/comments/class-list-comments-tool.php',
			'Get_Comment_Details_Tool'         => 'includes/tools/comments/class-get-comment-details-tool.php',
			'Create_Comment_Tool'              => 'includes/tools/comments/class-create-comment-tool.php',
			'Update_Comment_Tool'              => 'includes/tools/comments/class-update-comment-tool.php',
			'Delete_Comment_Tool'              => 'includes/tools/comments/class-delete-comment-tool.php',
			// Category tools
			'List_Categories_Tool'             => 'includes/tools/categories/class-list-categories-tool.php',
			'Get_Category_Details_Tool'        => 'includes/tools/categories/class-get-category-details-tool.php',
			'Create_Category_Tool'             => 'includes/tools/categories/class-create-category-tool.php',
			'Update_Category_Tool'             => 'includes/tools/categories/class-update-category-tool.php',
			'Delete_Category_Tool'             => 'includes/tools/categories/class-delete-category-tool.php',
			// Tag tools
			'List_Tags_Tool'                   => 'includes/tools/tags/class-list-tags-tool.php',
			'Get_Tag_Details_Tool'             => 'includes/tools/tags/class-get-tag-details-tool.php',
			'Create_Tag_Tool'                  => 'includes/tools/tags/class-create-tag-tool.php',
			'Update_Tag_Tool'                  => 'includes/tools/tags/class-update-tag-tool.php',
			'Delete_Tag_Tool'                  => 'includes/tools/tags/class-delete-tag-tool.php',
			// Media tools
			'List_Media_Tool'                  => 'includes/tools/media/class-list-media-tool.php',
			'Get_Media_Details_Tool'           => 'includes/tools/media/class-get-media-details-tool.php',
			'Create_Media_Tool'                => 'includes/tools/media/class-create-media-tool.php',
			'Update_Media_Tool'                => 'includes/tools/media/class-update-media-tool.php',
			'Delete_Media_Tool'                => 'includes/tools/media/class-delete-media-tool.php',
			// User tools
			'List_Users_Tool'                  => 'includes/tools/users/class-list-users-tool.php',
			'Get_User_Details_Tool'            => 'includes/tools/users/class-get-user-details-tool.php',
			'Get_Current_User_Tool'            => 'includes/tools/users/class-get-current-user-tool.php',
			'Create_User_Tool'                 => 'includes/tools/users/class-create-user-tool.php',
			'Update_User_Tool'                 => 'includes/tools/users/class-update-user-tool.php',
			'Delete_User_Tool'                 => 'includes/tools/users/class-delete-user-tool.php',
			'Send_Password_Reset_Tool'         => 'includes/tools/users/class-send-password-reset-tool.php',
			// Plugin tools
			'List_Installed_Plugins_Tool'      => 'includes/tools/plugins/class-list-installed-plugins-tool.php',
			'List_Active_Plugins_Tool'         => 'includes/tools/plugins/class-list-active-plugins-tool.php',
			'Get_Plugin_Details_Tool'          => 'includes/tools/plugins/class-get-plugin-details-tool.php',
			'Search_Plugins_Tool'              => 'includes/tools/plugins/class-search-plugins-tool.php',
			'Install_Plugin_Tool'              => 'includes/tools/plugins/class-install-plugin-tool.php',
			'Uninstall_Plugin_Tool'            => 'includes/tools/plugins/class-uninstall-plugin-tool.php',
			'Update_Plugins_Tool'              => 'includes/tools/plugins/class-update-plugins-tool.php',
			'Activate_Plugin_Tool'             => 'includes/tools/plugins/class-activate-plugin-tool.php',
			'Deactivate_Plugin_Tool'           => 'includes/tools/plugins/class-deactivate-plugin-tool.php',
			// Plugin file tools
			'List_Plugin_Files_Tool'           => 'includes/tools/plugins/class-list-plugin-files-tool.php',
			'Read_Plugin_File_Tool'            => 'includes/tools/plugins/class-read-plugin-file-tool.php',
			// Theme tools
			'List_Installed_Themes_Tool'       => 'includes/tools/themes/class-list-installed-themes-tool.php',
			'Get_Active_Theme_Tool'            => 'includes/tools/themes/class-get-active-theme-tool.php',
			'Get_Theme_Details_Tool'           => 'includes/tools/themes/class-get-theme-details-tool.php',
			'Search_Themes_Tool'               => 'includes/tools/themes/class-search-themes-tool.php',
			'Install_Theme_Tool'               => 'includes/tools/themes/class-install-theme-tool.php',
			'Uninstall_Theme_Tool'             => 'includes/tools/themes/class-uninstall-theme-tool.php',
			'Update_Themes_Tool'               => 'includes/tools/themes/class-update-themes-tool.php',
			'Activate_Theme_Tool'              => 'includes/tools/themes/class-activate-theme-tool.php',
			// Theme file tools
			'List_Theme_Files_Tool'            => 'includes/tools/themes/class-list-theme-files-tool.php',
			'Read_Theme_File_Tool'             => 'includes/tools/themes/class-read-theme-file-tool.php',
			// Debug log tools
			'Get_Debug_Log_Info_Tool'          => 'includes/tools/debug/class-get-debug-log-info-tool.php',
			'Read_Debug_Log_File_Tool'         => 'includes/tools/debug/class-read-debug-log-file-tool.php',
			// Options tools
			'List_Options_Tool'                => 'includes/tools/options/class-list-options-tool.php',
			'Get_Option_Value_Tool'            => 'includes/tools/options/class-get-option-value-tool.php',
			'Update_Option_Tool'               => 'includes/tools/options/class-update-option-tool.php',
			'Delete_Option_Tool'               => 'includes/tools/options/class-delete-option-tool.php',
			// Site tools
			'Get_Site_Info_Tool'               => 'includes/tools/site/class-get-site-info-tool.php',
			'Get_Site_Health_Tool'             => 'includes/tools/site/class-get-site-health-tool.php',
			'List_Available_Updates_Tool'      => 'includes/tools/site/class-list-available-updates-tool.php',
			'Update_Core_Tool'                 => 'includes/tools/site/class-update-core-tool.php',
			// Web tools
			'Send_Email_Tool'                  => 'includes/tools/web/class-send-email-tool.php',
			'Fetch_Url_Tool'                   => 'includes/tools/web/class-fetch-url-tool.php',
			'Download_File_Tool'               => 'includes/tools/web/class-download-file-tool.php',
			// Config tools
			'Configure_LLM_Provider_Tool'      => 'includes/tools/config/class-configure-llm-provider-tool.php',
			'Get_Chat_Model_Tool'              => 'includes/tools/config/class-get-chat-model-tool.php',
			'Get_Embeddings_Model_Tool'        => 'includes/tools/config/class-get-embeddings-model-tool.php',
			'List_Chat_Models_Tool'            => 'includes/tools/config/class-list-chat-models-tool.php',
			'List_Embeddings_Models_Tool'      => 'includes/tools/config/class-list-embeddings-models-tool.php',
			'Change_Chat_Model_Tool'           => 'includes/tools/config/class-change-chat-model-tool.php',
			'Change_Embeddings_Model_Tool'     => 'includes/tools/config/class-change-embeddings-model-tool.php',
			'Sync_Embeddings_Tool'             => 'includes/tools/config/class-sync-embeddings-tool.php',
			'Change_Chat_Position_Tool'        => 'includes/tools/config/class-change-chat-position-tool.php',
			// Role and capability tools
			'List_Roles_Tool'                  => 'includes/tools/roles/class-list-roles-tool.php',
			'Get_Role_Details_Tool'            => 'includes/tools/roles/class-get-role-details-tool.php',
			'List_Capabilities_Tool'           => 'includes/tools/roles/class-list-capabilities-tool.php',
			'Check_User_Capability_Tool'       => 'includes/tools/roles/class-check-user-capability-tool.php',
			'Add_Role_Tool'                    => 'includes/tools/roles/class-add-role-tool.php',
			'Remove_Role_Tool'                 => 'includes/tools/roles/class-remove-role-tool.php',
			'Clone_Role_Tool'                  => 'includes/tools/roles/class-clone-role-tool.php',
			'Add_Capability_To_Role_Tool'      => 'includes/tools/roles/class-add-capability-to-role-tool.php',
			'Remove_Capability_From_Role_Tool' => 'includes/tools/roles/class-remove-capability-from-role-tool.php',
			'Grant_User_Capability_Tool'       => 'includes/tools/roles/class-grant-user-capability-tool.php',
			'Revoke_User_Capability_Tool'      => 'includes/tools/roles/class-revoke-user-capability-tool.php',
			// System tools
			'Calculate_PHP_Tool'               => 'includes/tools/system/class-calculate-php-tool.php',
			'Read_File_Tool'                   => 'includes/tools/system/class-read-file-tool.php',
			'Write_File_Tool'                  => 'includes/tools/system/class-write-file-tool.php',
			'List_Files_Tool'                  => 'includes/tools/system/class-list-files-tool.php',
			'Delete_File_Tool'                 => 'includes/tools/system/class-delete-file-tool.php',
			// Menu tools
			'List_Menus_Tool'                  => 'includes/tools/menus/class-list-menus-tool.php',
			'Create_Menu_Tool'                 => 'includes/tools/menus/class-create-menu-tool.php',
			'Delete_Menu_Tool'                 => 'includes/tools/menus/class-delete-menu-tool.php',
			'Get_Menu_Details_Tool'            => 'includes/tools/menus/class-get-menu-details-tool.php',
			'Add_Menu_Item_Tool'               => 'includes/tools/menus/class-add-menu-item-tool.php',
			'Update_Menu_Item_Tool'            => 'includes/tools/menus/class-update-menu-item-tool.php',
			'Delete_Menu_Item_Tool'            => 'includes/tools/menus/class-delete-menu-item-tool.php',
			'List_Menu_Locations_Tool'         => 'includes/tools/menus/class-list-menu-locations-tool.php',
			'Assign_Menu_To_Location_Tool'     => 'includes/tools/menus/class-assign-menu-to-location-tool.php',
			'Unassign_Menu_From_Location_Tool' => 'includes/tools/menus/class-unassign-menu-from-location-tool.php',
			// Cron tools
			'WP_Cron_Event_List_Tool'          => 'includes/tools/cron/class-wp-cron-event-list-tool.php',
			'WP_Cron_Event_Details_Tool'       => 'includes/tools/cron/class-wp-cron-event-details-tool.php',
			'WP_Cron_Schedule_List_Tool'       => 'includes/tools/cron/class-wp-cron-schedule-list-tool.php',
			'WP_Cron_Event_Schedule_Tool'      => 'includes/tools/cron/class-wp-cron-event-schedule-tool.php',
			'WP_Cron_Event_Unschedule_Tool'    => 'includes/tools/cron/class-wp-cron-event-unschedule-tool.php',
			'WP_Cron_Run_Tool'                 => 'includes/tools/cron/class-wp-cron-run-tool.php',
			'WP_Cron_Event_Exists_Tool'        => 'includes/tools/cron/class-wp-cron-event-exists-tool.php',
			// Action Scheduler tools
			'Action_Scheduler_List_Tool'       => 'includes/tools/action-scheduler/class-action-scheduler-list-tool.php',
			'Action_Scheduler_Details_Tool'    => 'includes/tools/action-scheduler/class-action-scheduler-details-tool.php',
			'Action_Scheduler_Schedule_Tool'   => 'includes/tools/action-scheduler/class-action-scheduler-schedule-tool.php',
			'Action_Scheduler_Cancel_Tool'     => 'includes/tools/action-scheduler/class-action-scheduler-cancel-tool.php',
			'Action_Scheduler_Run_Tool'        => 'includes/tools/action-scheduler/class-action-scheduler-run-tool.php',
			'Action_Scheduler_Search_Tool'     => 'includes/tools/action-scheduler/class-action-scheduler-search-tool.php',
			// Shortcode tools
			'List_Shortcodes_Tool'             => 'includes/tools/shortcodes/class-list-shortcodes-tool.php',
			'Get_Shortcode_Details_Tool'       => 'includes/tools/shortcodes/class-get-shortcode-details-tool.php',
			'Render_Shortcode_Tool'            => 'includes/tools/shortcodes/class-render-shortcode-tool.php',
			// Post type tools (in content directory)
			'List_Post_Types_Tool'             => 'includes/tools/content/class-list-post-types-tool.php',
			'Get_Post_Type_Details_Tool'       => 'includes/tools/content/class-get-post-type-details-tool.php',
			// Custom post type tools
			'List_Custom_Posts_Tool'           => 'includes/tools/content/class-list-custom-posts-tool.php',
			'Get_Custom_Post_Tool'             => 'includes/tools/content/class-get-custom-post-tool.php',
			'Create_Custom_Post_Tool'          => 'includes/tools/content/class-create-custom-post-tool.php',
			'Update_Custom_Post_Tool'          => 'includes/tools/content/class-update-custom-post-tool.php',
			'Delete_Custom_Post_Tool'          => 'includes/tools/content/class-delete-custom-post-tool.php',
			// Taxonomy tools
			'List_Taxonomies_Tool'             => 'includes/tools/taxonomies/class-list-taxonomies-tool.php',
			'Get_Taxonomy_Details_Tool'        => 'includes/tools/taxonomies/class-get-taxonomy-details-tool.php',
			'List_Terms_Tool'                  => 'includes/tools/taxonomies/class-list-terms-tool.php',
			'Get_Term_Details_Tool'            => 'includes/tools/taxonomies/class-get-term-details-tool.php',
			'Create_Term_Tool'                 => 'includes/tools/taxonomies/class-create-term-tool.php',
			'Update_Term_Tool'                 => 'includes/tools/taxonomies/class-update-term-tool.php',
			'Delete_Term_Tool'                 => 'includes/tools/taxonomies/class-delete-term-tool.php',
			'Term_Exists_Tool'                 => 'includes/tools/taxonomies/class-term-exists-tool.php',

			// Provider classes
			'Provider_Type'                    => 'includes/providers/class-provider-type.php',
			'Provider_OpenAI'                  => 'includes/providers/class-provider-openai.php',
			'Provider_Anthropic'               => 'includes/providers/class-provider-anthropic.php',
			'Provider_OpenRouter'              => 'includes/providers/class-provider-openrouter.php',
			'Provider_Ollama_Cloud'            => 'includes/providers/class-provider-ollama-cloud.php',

			// Model classes
			'LLM'                              => 'includes/models/class-llm.php',
			'LLM_Chat'                         => 'includes/models/class-llm-chat.php',
			'LLM_Chat_OpenAI'                  => 'includes/models/class-llm-chat-openai.php',
			'LLM_Chat_Anthropic'               => 'includes/models/class-llm-chat-anthropic.php',
			'LLM_Chat_OpenRouter'              => 'includes/models/class-llm-chat-openrouter.php',
			'LLM_Chat_Ollama_Cloud'            => 'includes/models/class-llm-chat-ollama-cloud.php',
			'LLM_Embedding'                    => 'includes/models/class-llm-embedding.php',
			'LLM_Embedding_OpenAI'             => 'includes/models/class-llm-embedding-openai.php',
			'LLM_Embedding_OpenRouter'         => 'includes/models/class-llm-embedding-openrouter.php',
			'Context'                          => 'includes/models/class-context.php',
			'Context_OpenAI'                   => 'includes/models/class-context-openai.php',
			'Context_Anthropic'                => 'includes/models/class-context-anthropic.php',
			'Context_OpenRouter'               => 'includes/models/class-context-openrouter.php',
			'Context_Ollama_Cloud'             => 'includes/models/class-context-ollama-cloud.php',
			'Tool_Call'                        => 'includes/models/class-tool-call.php',

			// Message classes
			'Message'                          => 'includes/messages/class-message.php',
			'System_Message'                   => 'includes/messages/class-system-message.php',
			'User_Message'                     => 'includes/messages/class-user-message.php',
			'Assistant_Message'                => 'includes/messages/class-assistant-message.php',
			'Tool_Call_Message'                => 'includes/messages/class-tool-call-message.php',
			'Tool_Result_Message'              => 'includes/messages/class-tool-result-message.php',

			// Context pruning classes
			'Token_Counter'                    => 'includes/class-token-counter.php',
			'Model_Info'                       => 'includes/class-model-info.php',
			'Context_Pruner'                   => 'includes/class-context-pruner.php',
			'Rate_Limiter'                     => 'includes/class-rate-limiter.php',

			// Event Queue classes
			'Event_Queue'                      => 'includes/class-event-queue.php',
			'SSE_Connection'                   => 'includes/sse/class-sse-connection.php',

			// Event base classes
			'Event'                            => 'includes/sse/events/class-event.php',
			'User_Event'                       => 'includes/sse/events/class-user-event.php',
			'Thread_Event'                     => 'includes/sse/events/class-thread-event.php',

			// Event classes
			'Events\\Message_Event'            => 'includes/sse/events/class-message-event.php',
			'Events\\Stream_Chunk_Event'       => 'includes/sse/events/class-stream-chunk-event.php',
			'Events\\Control_Event'            => 'includes/sse/events/class-control-event.php',
			'Events\\Thread_Error_Event'       => 'includes/sse/events/class-thread-error-event.php',
			'Events\\Progress_Event'           => 'includes/sse/events/class-progress-event.php',

			// Progress tracking
			'Progress_Tracker'                 => 'includes/class-progress-tracker.php',
		);
	}

	/**
	 * Register the autoloader
	 * @since     1.0.0
	 */
	public function register() {
		spl_autoload_register( array( $this, 'autoload' ) );
	}

	/**
	 * Autoload classes based on the explicit class map
	 *
	 * Looks up the class in our predefined mapping and loads the corresponding file.
	 * Only handles classes in the Agenistrator namespace.
	 *
	 * @param      string  $fqcn  The fully qualified class name
	 * @since     1.0.0
	 */
	public function autoload( $fqcn ) {
		// Only handle classes in our namespace
		$prefix = 'Agenistrator\\';
		if ( strncmp( $fqcn, $prefix, strlen( $prefix ) ) !== 0 ) {
			return;
		}

		// Get the class name without namespace
		$class_name = substr( $fqcn, strlen( $prefix ) );

		// Check if we have a mapping for this class
		if ( isset( $this->class_map[ $class_name ] ) ) {
			$file_path = $this->plugin_dir . $this->class_map[ $class_name ];

			if ( file_exists( $file_path ) ) {
				require_once $file_path;
				return;
			}
		}

		// Debug logging for missing classes
		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Production error logging for debugging class loading issues
			error_log( "Failed to autoload class: {$fqcn} - No mapping found or file doesn't exist" );
		}
	}
}
