<?php
/**
 * WAMP Installation Detector
 * Focused specifically on WAMP/WAMP64 installations across different drives
 */

class WampDetector {
    private static $detectedPaths = null;
    private static $cacheFile = 'wamp_detection_cache.json';
    
    /**
     * Get WAMP installation details
     * @return array Array with mysql_bin_path, wamp_root, server_type
     */
    public static function detect() {
        // Check cache first
        if (self::$detectedPaths !== null) {
            return self::$detectedPaths;
        }
        
        // Try to load from cache file
        $cached = self::loadFromCache();
        if ($cached !== null) {
            self::$detectedPaths = $cached;
            return $cached;
        }
        
        // Perform fresh detection
        $result = self::performDetection();
        
        // Cache the result
        self::saveToCache($result);
        self::$detectedPaths = $result;
        
        return $result;
    }
    
    /**
     * Force re-detection (ignores cache)
     */
    public static function forceDetect() {
        self::$detectedPaths = null;
        self::clearCache();
        return self::detect();
    }
    
    /**
     * Get mysqldump executable path
     */
    public static function getMysqldumpPath() {
        $detection = self::detect();
        return $detection['mysqldump_path'] ?? null;
    }
    
    /**
     * Get mysql executable path
     */
    public static function getMysqlPath() {
        $detection = self::detect();
        return $detection['mysql_path'] ?? null;
    }
    
    /**
     * Check if MySQL tools are available
     */
    public static function isMysqlAvailable() {
        $detection = self::detect();
        return !empty($detection['mysqldump_path']) && file_exists($detection['mysqldump_path']);
    }
    
    /**
     * Get WAMP installation status
     */
    public static function getWampStatus() {
        $detection = self::detect();
        return [
            'detected' => !empty($detection['wamp_root']),
            'wamp_root' => $detection['wamp_root'],
            'wamp_type' => $detection['server_type'],
            'mysql_version' => $detection['mysql_version'],
            'mysqldump_available' => self::isMysqlAvailable()
        ];
    }
    
    private static function performDetection() {
        $result = [
            'server_type' => 'unknown',
            'wamp_root' => null,
            'mysql_bin_path' => null,
            'mysqldump_path' => null,
            'mysql_path' => null,
            'mysql_version' => null,
            'detection_time' => time(),
            'detection_details' => []
        ];
        
        // Common drive letters where WAMP might be installed
        $drives = ['C', 'D', 'E', 'F', 'G', 'H'];
        
        // WAMP possible directory structures (WAMP only)
        $wampPaths = [
            'wamp64/bin/mysql',
            'wamp/bin/mysql'
        ];
        
        foreach ($drives as $drive) {
            foreach ($wampPaths as $wampPath) {
                $basePath = $drive . ':\\' . $wampPath;
                $result['detection_details'][] = "Checking: {$basePath}";
                
                if (is_dir($basePath)) {
                    $result['detection_details'][] = "Found WAMP directory: {$basePath}";
                    
                    // Found a MySQL directory, now find the version subdirectory
                    $versionDirs = self::findMysqlVersions($basePath);
                    
                    if (!empty($versionDirs)) {
                        $latestVersion = $versionDirs[0]; // Get the latest version
                        $binPath = $basePath . '\\' . $latestVersion . '\\bin';
                        
                        $result['detection_details'][] = "Found MySQL version: {$latestVersion}";
                        $result['detection_details'][] = "Checking bin path: {$binPath}";
                        
                        if (is_dir($binPath)) {
                            $mysqldumpPath = $binPath . '\\mysqldump.exe';
                            $mysqlPath = $binPath . '\\mysql.exe';
                            
                            $result['detection_details'][] = "Checking mysqldump: {$mysqldumpPath}";
                            
                            if (file_exists($mysqldumpPath)) {
                                $result['server_type'] = self::detectServerType($wampPath);
                                $result['wamp_root'] = dirname(dirname($basePath));
                                $result['mysql_bin_path'] = $binPath;
                                $result['mysqldump_path'] = $mysqldumpPath;
                                $result['mysql_path'] = $mysqlPath;
                                $result['mysql_version'] = $latestVersion;
                                
                                $result['detection_details'][] = "WAMP detected successfully!";
                                
                                // Test the mysqldump to make sure it works
                                if (self::testMysqldump($mysqldumpPath)) {
                                    $result['detection_details'][] = "mysqldump test passed";
                                    return $result;
                                } else {
                                    $result['detection_details'][] = "mysqldump test failed";
                                }
                            } else {
                                $result['detection_details'][] = "mysqldump.exe not found";
                            }
                        } else {
                            $result['detection_details'][] = "MySQL bin directory not found";
                        }
                    } else {
                        $result['detection_details'][] = "No MySQL version directories found";
                    }
                }
            }
        }
        
        // Fallback: Check if mysqldump is in system PATH
        $result['detection_details'][] = "Checking system PATH for mysqldump";
        exec('where mysqldump 2>nul', $output, $returnCode);
        if ($returnCode === 0 && !empty($output)) {
            $result['mysqldump_path'] = 'mysqldump'; // Use from PATH
            $result['mysql_path'] = 'mysql';
            $result['server_type'] = 'system_path';
            $result['detection_details'][] = "Found mysqldump in system PATH";
            
            // Get version from PATH
            exec('mysqldump --version 2>&1', $versionOutput);
            if (!empty($versionOutput)) {
                $result['mysql_version'] = self::extractVersionFromOutput($versionOutput[0]);
                $result['detection_details'][] = "MySQL version from PATH: {$result['mysql_version']}";
            }
        } else {
            $result['detection_details'][] = "mysqldump not found in system PATH";
        }
        
        return $result;
    }
    
    private static function findMysqlVersions($basePath) {
        if (!is_dir($basePath)) {
            return [];
        }
        
        $versions = [];
        $dirs = scandir($basePath);
        
        foreach ($dirs as $dir) {
            if ($dir === '.' || $dir === '..') continue;
            
            $fullPath = $basePath . '\\' . $dir;
            if (is_dir($fullPath) && preg_match('/mysql[\d\.]+/i', $dir)) {
                $versions[] = $dir;
            }
        }
        
        // Sort versions (newest first)
        usort($versions, function($a, $b) {
            return version_compare(
                preg_replace('/[^\d\.]/', '', $b), 
                preg_replace('/[^\d\.]/', '', $a)
            );
        });
        
        return $versions;
    }
    
    private static function detectServerType($path) {
        if (stripos($path, 'wamp64') !== false) return 'wamp64';
        if (stripos($path, 'wamp') !== false) return 'wamp';
        return 'unknown';
    }
    
    private static function testMysqldump($path) {
        // Quick test to see if mysqldump is executable
        $command = escapeshellarg($path) . ' --version 2>&1';
        exec($command, $output, $returnCode);
        
        return $returnCode === 0 && !empty($output);
    }
    
    private static function extractVersionFromOutput($output) {
        if (preg_match('/(\d+\.\d+\.\d+)/', $output, $matches)) {
            return $matches[1];
        }
        return 'unknown';
    }
    
    private static function loadFromCache() {
        if (!file_exists(self::$cacheFile)) {
            return null;
        }
        
        $content = file_get_contents(self::$cacheFile);
        $data = json_decode($content, true);
        
        if (!$data || !isset($data['detection_time'])) {
            return null;
        }
        
        // Cache expires after 24 hours
        if (time() - $data['detection_time'] > 86400) {
            return null;
        }
        
        // Verify cached paths still exist
        if (!empty($data['mysqldump_path']) && $data['mysqldump_path'] !== 'mysqldump') {
            if (!file_exists($data['mysqldump_path'])) {
                return null;
            }
        }
        
        return $data;
    }
    
    private static function saveToCache($data) {
        file_put_contents(self::$cacheFile, json_encode($data, JSON_PRETTY_PRINT));
    }
    
    private static function clearCache() {
        if (file_exists(self::$cacheFile)) {
            unlink(self::$cacheFile);
        }
    }
    
    /**
     * Get detailed diagnostic information
     */
    public static function getDiagnostics() {
        $detection = self::detect();
        $diagnostics = [];
        
        // Test mysqldump availability
        if (!empty($detection['mysqldump_path'])) {
            $command = ($detection['mysqldump_path'] === 'mysqldump') ? 
                'mysqldump --version 2>&1' : 
                escapeshellarg($detection['mysqldump_path']) . ' --version 2>&1';
            
            exec($command, $output, $returnCode);
            
            $diagnostics['mysqldump_test'] = [
                'path' => $detection['mysqldump_path'],
                'executable' => $returnCode === 0,
                'version_output' => implode("\n", $output),
                'return_code' => $returnCode
            ];
        }
        
        // Test mysql availability
        if (!empty($detection['mysql_path'])) {
            $command = ($detection['mysql_path'] === 'mysql') ? 
                'mysql --version 2>&1' : 
                escapeshellarg($detection['mysql_path']) . ' --version 2>&1';
            
            exec($command, $output, $returnCode);
            
            $diagnostics['mysql_test'] = [
                'path' => $detection['mysql_path'],
                'executable' => $returnCode === 0,
                'version_output' => implode("\n", $output),
                'return_code' => $returnCode
            ];
        }
        
        $diagnostics['detection_result'] = $detection;
        
        return $diagnostics;
    }
    
    /**
     * Get recommended backup directory based on WAMP installation
     */
    public static function getRecommendedBackupPath() {
        $detection = self::detect();
        
        if (!empty($detection['wamp_root'])) {
            // Use same drive as WAMP installation
            $drive = substr($detection['wamp_root'], 0, 2); // Get drive letter (e.g., "C:")
            
            // Use the correct WAMP type (wamp or wamp64)
            $wampType = $detection['server_type'] ?? 'wamp';
            return $drive . '/' . $wampType . '/backups/itrpos/';
        }
        
        // Fallback to D: drive
        return 'D:/wamp/backups/itrpos/';
    }
    
    /**
     * Test if a backup directory is writable and create it if needed
     */
    public static function testBackupDirectory($path) {
        $result = [
            'path' => $path,
            'exists' => false,
            'writable' => false,
            'can_create' => false,
            'error' => null
        ];
        
        // Check if directory exists
        if (is_dir($path)) {
            $result['exists'] = true;
            $result['writable'] = is_writable($path);
        } else {
            // Try to create the directory
            try {
                if (mkdir($path, 0755, true)) {
                    $result['exists'] = true;
                    $result['writable'] = true;
                    $result['can_create'] = true;
                } else {
                    $result['error'] = "Failed to create directory";
                }
            } catch (Exception $e) {
                $result['error'] = $e->getMessage();
            }
        }
        
        return $result;
    }
    
    /**
     * Get all available drives for backup
     */
    public static function getAvailableDrives() {
        $drives = [];
        $driveLetters = ['C', 'D', 'E', 'F', 'G', 'H'];
        
        foreach ($driveLetters as $letter) {
            $drivePath = $letter . ':/';
            if (is_dir($drivePath)) {
                $freeSpace = disk_free_space($drivePath);
                $totalSpace = disk_total_space($drivePath);
                $usedSpace = $totalSpace - $freeSpace;
                
                $drives[] = [
                    'letter' => $letter,
                    'path' => $drivePath,
                    'free_space' => $freeSpace,
                    'total_space' => $totalSpace,
                    'used_space' => $usedSpace,
                    'free_space_gb' => round($freeSpace / (1024 * 1024 * 1024), 2),
                    'total_space_gb' => round($totalSpace / (1024 * 1024 * 1024), 2)
                ];
            }
        }
        
        return $drives;
    }
}
?>
