<?php
/**
 * AI Auto Tool - Class Mapping System
 * 
 * Tự động tạo và quản lý class map để tối ưu hóa autoloader
 * 
 * @package AI Auto Tool
 * @version 2.3.0
 */

if ( ! defined( 'ABSPATH' ) ) exit; // Thoát nếu truy cập trực tiếp

class AIAutoTool_ClassMapper {
    
    /**
     * Class map cache file
     */
    const CACHE_FILE = 'class-map-cache.json';
    
    /**
     * Generate and cache class map
     */
    public static function generateClassMap() {
        $pluginDir = plugin_dir_path(__FILE__) . '../';
        $cacheFile = $pluginDir . 'cache/' . self::CACHE_FILE;
        
        // Create cache directory if not exists
        $cacheDir = dirname($cacheFile);
        if (!is_dir($cacheDir)) {
            wp_mkdir_p($cacheDir);
        }
        
        // Check if cache is valid
        if (self::isCacheValid($cacheFile)) {
            return self::loadCachedClassMap($cacheFile);
        }
        
        // Generate new class map
        $classMap = self::scanForClasses($pluginDir);
        
        // Cache the class map
        self::cacheClassMap($cacheFile, $classMap);
        
        return $classMap;
    }
    
    /**
     * Scan directories for classes
     */
    private static function scanForClasses($pluginDir) {
        $classMap = array();
        
        // Add rendersetting first (required by many classes)
        $rendersettingFile = $pluginDir . 'lib/setting.php';
        if (file_exists($rendersettingFile)) {
            $classes = self::extractClassesFromFile($rendersettingFile);
            foreach ($classes as $className) {
                $classMap[$className] = $rendersettingFile;
            }
        }
        
        // Directories to scan
        $directories = array(
            'inc/' => 'AIAutoTool\\Legacy\\',
            'lib/' => 'AIAutoTool\\Lib\\'
            // 'inc/ai-providers/' => 'AIAutoTool\\AIProviders\\',
            // 'inc/extra-config/' => 'AIAutoTool\\ExtraConfig\\',
        );
        
        foreach ($directories as $dir => $namespace) {
            $fullDir = $pluginDir . $dir;
            
            if (!is_dir($fullDir)) {
                continue;
            }
            
            try {
                // Use SKIP_DOTS to prevent issues with . and .. entries
                $files = new RecursiveIteratorIterator(
                    new RecursiveDirectoryIterator($fullDir, RecursiveDirectoryIterator::SKIP_DOTS),
                    RecursiveIteratorIterator::LEAVES_ONLY
                );
                
                // Exclude these directories to prevent scanning vendor/, cache/, etc.
                $excludedDirs = array('vendor', 'node_modules', 'cache', '.git', 'docs', 'tmpcode');
                
                foreach ($files as $file) {
                    // Skip excluded directories
                    $filePath = $file->getPathname();
                    $relativePath = str_replace($pluginDir, '', $filePath);
                    $pathParts = explode('/', $relativePath);
                    
                    $shouldExclude = false;
                    foreach ($pathParts as $part) {
                        if (in_array($part, $excludedDirs)) {
                            $shouldExclude = true;
                            break;
                        }
                    }
                    
                    if ($shouldExclude) {
                        continue;
                    }
                    
                    if ($file->isFile() && $file->getExtension() === 'php') {
                        // Limit file size to prevent memory issues (skip files larger than 1MB)
                        if ($file->getSize() > 1048576) {
                            continue;
                        }
                        
                        try {
                            $classes = self::extractClassesFromFile($file->getPathname());
                            
                            foreach ($classes as $className) {
                                // Create namespace-based class name
                                $relativePath = str_replace($fullDir, '', $file->getPathname());
                                $relativePath = str_replace('.php', '', $relativePath);
                                $relativePath = str_replace('/', '\\', $relativePath);
                                
                                $namespacedClass = $namespace . $relativePath;
                                
                                $classMap[$className] = $file->getPathname();
                                $classMap[$namespacedClass] = $file->getPathname();
                            }
                        } catch (Exception $e) {
                            // Skip files that cause errors to prevent breaking the scan
                            if (defined('WP_DEBUG') && WP_DEBUG) {
                            }
                            continue;
                        }
                    }
                }
            } catch (Exception $e) {
                // Skip directories that cause errors
                if (defined('WP_DEBUG') && WP_DEBUG) {
                }
                continue;
            }
        }
        
        return $classMap;
    }
    
    /**
     * Extract class names from PHP file
     */
    private static function extractClassesFromFile($filePath) {
        $classes = array();
        $content = file_get_contents($filePath);
        
        // Extract class names
        if (preg_match_all('/^class\s+([a-zA-Z_][a-zA-Z0-9_]*)/m', $content, $matches)) {
            $classes = array_merge($classes, $matches[1]);
        }
        
        // Extract interface names
        if (preg_match_all('/^interface\s+([a-zA-Z_][a-zA-Z0-9_]*)/m', $content, $matches)) {
            $classes = array_merge($classes, $matches[1]);
        }
        
        // Extract trait names
        if (preg_match_all('/^trait\s+([a-zA-Z_][a-zA-Z0-9_]*)/m', $content, $matches)) {
            $classes = array_merge($classes, $matches[1]);
        }
        
        return array_unique($classes);
    }
    
    /**
     * Check if cache is valid
     */
    private static function isCacheValid($cacheFile) {
        if (!file_exists($cacheFile)) {
            return false;
        }
        
        // Cache expires after 24 hours
        $cacheTime = filemtime($cacheFile);
        $expiryTime = 24 * 60 * 60; // 24 hours
        
        return (time() - $cacheTime) < $expiryTime;
    }
    
    /**
     * Load cached class map
     */
    private static function loadCachedClassMap($cacheFile) {
        $content = file_get_contents($cacheFile);
        return json_decode($content, true);
    }
    
    /**
     * Cache class map
     */
    private static function cacheClassMap($cacheFile, $classMap) {
        $content = json_encode($classMap, JSON_PRETTY_PRINT);
        file_put_contents($cacheFile, $content);
    }
    
    /**
     * Clear class map cache
     */
    public static function clearCache() {
        $pluginDir = plugin_dir_path(__FILE__) . '../';
        $cacheFile = $pluginDir . 'cache/' . self::CACHE_FILE;
        
        if (file_exists($cacheFile)) {
            unlink($cacheFile);
        }
    }
    
    /**
     * Get class map statistics
     */
    public static function getStats() {
        $classMap = self::generateClassMap();
        
        $stats = array(
            'total_classes' => count($classMap),
            'by_namespace' => array(),
            'file_sizes' => array(),
        );
        
        foreach ($classMap as $className => $filePath) {
            // Count by namespace
            $namespace = self::extractNamespace($className);
            if (!isset($stats['by_namespace'][$namespace])) {
                $stats['by_namespace'][$namespace] = 0;
            }
            $stats['by_namespace'][$namespace]++;
            
            // Calculate file sizes
            if (file_exists($filePath)) {
                $stats['file_sizes'][$className] = filesize($filePath);
            }
        }
        
        return $stats;
    }
    
    /**
     * Extract namespace from class name
     */
    private static function extractNamespace($className) {
        $parts = explode('\\', $className);
        return $parts[0] . '\\' . $parts[1] . '\\';
    }
    
    /**
     * Optimize class map for performance
     */
    public static function optimizeClassMap() {
        $classMap = self::generateClassMap();
        
        // Sort by frequency of use (most used first)
        $optimizedMap = array();
        
        // Core classes first
        $coreClasses = array(
            'AIAutoTool\\Core\\Plugin',
            'AIAutoTool\\Core\\Settings',
            'AIAutoTool\\Core\\API',
            'AIAutoTool\\Core\\OptimizedLoader',
        );
        
        foreach ($coreClasses as $className) {
            if (isset($classMap[$className])) {
                $optimizedMap[$className] = $classMap[$className];
                unset($classMap[$className]);
            }
        }
        
        // Add remaining classes
        $optimizedMap = array_merge($optimizedMap, $classMap);
        
        return $optimizedMap;
    }
    
    /**
     * Generate autoloader configuration
     */
    public static function generateAutoloaderConfig() {
        $classMap = self::optimizeClassMap();
        
        $config = array(
            'classMap' => $classMap,
            'psr4' => array(
                'AIAutoTool\\Core\\' => array('inc/core/'),
                'AIAutoTool\\Features\\' => array('inc/features/'),
                'AIAutoTool\\AIProviders\\' => array('inc/ai-providers/'),
                'AIAutoTool\\ExtraConfig\\' => array('inc/extra-config/'),
                'AIAutoTool\\Lib\\' => array('lib/'),
                'AIAutoTool\\Legacy\\' => array('inc/'),
            ),
            'fallbackDirs' => array(
                'inc/',
                'lib/',
                'inc/ai-providers/',
                'inc/extra-config/',
            ),
        );
        
        return $config;
    }
    
    /**
     * Export class map for debugging
     */
    public static function exportClassMap() {
        $classMap = self::generateClassMap();
        $stats = self::getStats();
        
        $export = array(
            'generated_at' => date('Y-m-d H:i:s'),
            'total_classes' => count($classMap),
            'statistics' => $stats,
            'class_map' => $classMap,
        );
        
        return $export;
    }
}

// Auto-generate class map on admin init
add_action('admin_init', function() {
    if (isset($_GET['aiautotool_generate_classmap']) && current_user_can('manage_options')) {
        AIAutoTool_ClassMapper::generateClassMap();
        wp_redirect(admin_url('admin.php?page=aiautotool-features&classmap_generated=1'));
        exit;
    }
});
?>
