<?php
/**
 * Windows Task Scheduler Manager
 * Automatically creates and manages Windows Task Scheduler entries for backup automation
 */

class WindowsTaskManager {
    private $taskName = 'ITRPOS Backup Scheduler';
    private $scriptPath;
    private $phpPath;
    
    public function __construct() {
        // Auto-detect the correct script path
        $this->scriptPath = $this->detectScriptPath();
        $this->phpPath = $this->findPhpPath();
        
        // Set timezone - use default for Windows Task Manager
        // The backup scheduler will handle timezone from database when it runs
        date_default_timezone_set('Asia/Karachi');
    }
    
    /**
     * Auto-detect the correct script path for this installation
     */
    private function detectScriptPath() {
        // Get the current working directory (should be the ITRPOS root)
        $currentDir = getcwd();
        
        // Try to find backup_scheduler.php in the current directory
        $scriptPath = $currentDir . DIRECTORY_SEPARATOR . 'backup_scheduler.php';
        if (file_exists($scriptPath)) {
            return $scriptPath;
        }
        
        // Fallback to relative path from this handler
        $relativePath = __DIR__ . '/../backup_scheduler.php';
        if (file_exists($relativePath)) {
            return $relativePath;
        }
        
        // Last resort - use current directory
        return $currentDir . DIRECTORY_SEPARATOR . 'backup_scheduler.php';
    }
    
    /**
     * Find PHP executable path - Auto-detect for any WAMP installation
     */
    private function findPhpPath() {
        // First, try to get PHP path from current environment
        $phpPath = PHP_BINARY;
        if ($phpPath && file_exists($phpPath) && strpos($phpPath, 'php.exe') !== false) {
            return $phpPath;
        }
        
        // Try to find PHP in common WAMP locations
        $possiblePaths = [
            // Current directory (if PHP is in PATH)
            'php.exe',
            
            // WAMP variations
            'C:\\wamp\\bin\\php\\php8.3.0\\php.exe',
            'C:\\wamp\\bin\\php\\php8.2.0\\php.exe',
            'C:\\wamp\\bin\\php\\php8.1.0\\php.exe',
            'C:\\wamp\\bin\\php\\php8.0.0\\php.exe',
            'C:\\wamp\\bin\\php\\php7.4.0\\php.exe',
            'C:\\wamp\\bin\\php\\php7.3.0\\php.exe',
            
            // WAMP64 variations
            'C:\\wamp64\\bin\\php\\php8.3.0\\php.exe',
            'C:\\wamp64\\bin\\php\\php8.2.0\\php.exe',
            'C:\\wamp64\\bin\\php\\php8.1.0\\php.exe',
            'C:\\wamp64\\bin\\php\\php8.0.0\\php.exe',
            'C:\\wamp64\\bin\\php\\php7.4.0\\php.exe',
            'C:\\wamp64\\bin\\php\\php7.3.0\\php.exe',
            
            // XAMPP variations
            'C:\\xampp\\php\\php.exe',
            'C:\\xampp\\php\\php8.3.0\\php.exe',
            'C:\\xampp\\php\\php8.2.0\\php.exe',
            'C:\\xampp\\php\\php8.1.0\\php.exe',
            'C:\\xampp\\php\\php8.0.0\\php.exe',
            'C:\\xampp\\php\\php7.4.0\\php.exe',
            
            // Laragon variations
            'C:\\laragon\\bin\\php\\php8.3.0\\php.exe',
            'C:\\laragon\\bin\\php\\php8.2.0\\php.exe',
            'C:\\laragon\\bin\\php\\php8.1.0\\php.exe',
            'C:\\laragon\\bin\\php\\php8.0.0\\php.exe',
            'C:\\laragon\\bin\\php\\php7.4.0\\php.exe',
            
            // Standalone PHP
            'C:\\php\\php.exe',
            'C:\\php8\\php.exe',
            'C:\\php7\\php.exe'
        ];
        
        foreach ($possiblePaths as $path) {
            if (file_exists($path)) {
                return $path;
            }
        }
        
        // Try to find PHP in system PATH
        $pathOutput = [];
        $returnCode = 0;
        exec('where php.exe 2>nul', $pathOutput, $returnCode);
        
        if ($returnCode === 0 && !empty($pathOutput)) {
            $phpPath = trim($pathOutput[0]);
            if (file_exists($phpPath) && strpos($phpPath, 'php.exe') !== false) {
                return $phpPath;
            }
        }
        
        // Try to find PHP using which command (alternative)
        $pathOutput = [];
        $returnCode = 0;
        exec('which php 2>nul', $pathOutput, $returnCode);
        
        if ($returnCode === 0 && !empty($pathOutput)) {
            $phpPath = trim($pathOutput[0]);
            if (file_exists($phpPath) && strpos($phpPath, 'php') !== false) {
                return $phpPath;
            }
        }
        
        // Try to find PHP in current WAMP installation directory
        $currentDir = getcwd();
        if (strpos($currentDir, 'wamp64') !== false) {
            $wampRoot = str_replace('\\www\\itrpos', '', $currentDir);
            $phpDirs = glob($wampRoot . '\\bin\\php\\php*');
            if (!empty($phpDirs)) {
                $latestPhpDir = end($phpDirs);
                $phpPath = $latestPhpDir . '\\php.exe';
                if (file_exists($phpPath)) {
                    return $phpPath;
                }
            }
        }
        
        // Last resort - use php.exe and hope it's in PATH
        return 'php.exe';
    }
    
    /**
     * Create Windows Task Scheduler entry
     */
    public function createBackupTask() {
        try {
            // Verify paths exist before creating task
            if (!file_exists($this->phpPath)) {
                return [
                    'success' => false,
                    'message' => 'PHP executable not found',
                    'error' => "PHP path does not exist: {$this->phpPath}",
                    'php_path' => $this->phpPath
                ];
            }
            
            if (!file_exists($this->scriptPath)) {
                return [
                    'success' => false,
                    'message' => 'Backup scheduler script not found',
                    'error' => "Script path does not exist: {$this->scriptPath}",
                    'script_path' => $this->scriptPath
                ];
            }
            
            // Build the schtasks command with proper escaping
            // Try without /ru SYSTEM first (for non-admin environments)
            $command = sprintf(
                'schtasks /create /tn "%s" /tr "\"%s\" \"%s\"" /sc minute /mo 1 /f',
                $this->taskName,
                $this->phpPath,
                $this->scriptPath
            );
            
            // Execute the command
            exec($command . ' 2>&1', $output, $returnCode);
            
            if ($returnCode === 0) {
                return [
                    'success' => true,
                    'message' => 'Windows Task Scheduler created successfully',
                    'output' => implode("\n", $output),
                    'php_path' => $this->phpPath,
                    'script_path' => $this->scriptPath,
                    'command' => $command
                ];
            } else {
                // Try with SYSTEM account as fallback
                $systemCommand = sprintf(
                    'schtasks /create /tn "%s" /tr "\"%s\" \"%s\"" /sc minute /mo 1 /f /ru SYSTEM',
                    $this->taskName,
                    $this->phpPath,
                    $this->scriptPath
                );
                
                exec($systemCommand . ' 2>&1', $systemOutput, $systemReturnCode);
                
                if ($systemReturnCode === 0) {
                    return [
                        'success' => true,
                        'message' => 'Windows Task Scheduler created successfully (with SYSTEM account)',
                        'output' => implode("\n", $systemOutput),
                        'php_path' => $this->phpPath,
                        'script_path' => $this->scriptPath,
                        'command' => $systemCommand
                    ];
                } else {
                    return [
                        'success' => false,
                        'message' => 'Failed to create Windows Task Scheduler - Access denied. Please run as administrator or manually create the task.',
                        'error' => implode("\n", $output),
                        'system_error' => implode("\n", $systemOutput),
                        'command' => $command,
                        'system_command' => $systemCommand,
                        'php_path' => $this->phpPath,
                        'script_path' => $this->scriptPath,
                        'solution' => 'Run the backup management page as administrator or manually create the Windows Task Scheduler task.'
                    ];
                }
            }
            
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => 'Exception occurred while creating task',
                'error' => $e->getMessage(),
                'php_path' => $this->phpPath,
                'script_path' => $this->scriptPath
            ];
        }
    }
    
    /**
     * Remove Windows Task Scheduler entry
     */
    public function removeBackupTask() {
        try {
            $command = sprintf('schtasks /delete /tn "%s" /f', $this->taskName);
            exec($command . ' 2>&1', $output, $returnCode);
            
            if ($returnCode === 0) {
                return [
                    'success' => true,
                    'message' => 'Windows Task Scheduler removed successfully',
                    'output' => implode("\n", $output)
                ];
            } else {
                return [
                    'success' => false,
                    'message' => 'Failed to remove Windows Task Scheduler',
                    'error' => implode("\n", $output)
                ];
            }
            
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => 'Exception occurred while removing task',
                'error' => $e->getMessage()
            ];
        }
    }
    
    /**
     * Check if Windows Task Scheduler is running
     */
    public function isTaskRunning() {
        try {
            $command = sprintf('schtasks /query /tn "%s" /fo csv', $this->taskName);
            exec($command . ' 2>&1', $output, $returnCode);
            
            if ($returnCode === 0) {
                $outputString = implode("\n", $output);
                // Check if task exists and is ready
                return strpos($outputString, $this->taskName) !== false && 
                       strpos($outputString, 'Ready') !== false;
            }
            
            return false;
            
        } catch (Exception $e) {
            return false;
        }
    }
    
    /**
     * Get task status information
     */
    public function getTaskStatus() {
        try {
            $command = sprintf('schtasks /query /tn "%s" /fo csv', $this->taskName);
            exec($command . ' 2>&1', $output, $returnCode);
            
            if ($returnCode === 0) {
                $outputString = implode("\n", $output);
                $lines = explode("\n", $outputString);
                
                if (count($lines) >= 2) {
                    $headers = str_getcsv($lines[0]);
                    $data = str_getcsv($lines[1]);
                    
                    $status = [];
                    for ($i = 0; $i < count($headers); $i++) {
                        $status[$headers[$i]] = $data[$i] ?? '';
                    }
                    
                    return [
                        'exists' => true,
                        'status' => $status
                    ];
                }
            }
            
            return [
                'exists' => false,
                'status' => null
            ];
            
        } catch (Exception $e) {
            return [
                'exists' => false,
                'status' => null,
                'error' => $e->getMessage()
            ];
        }
    }
    
    /**
     * Test if schtasks command is available
     */
    public function isSchtasksAvailable() {
        try {
            exec('schtasks /? 2>&1', $output, $returnCode);
            return $returnCode === 0;
        } catch (Exception $e) {
            return false;
        }
    }
    
    /**
     * Get system information
     */
    public function getSystemInfo() {
        return [
            'php_path' => $this->phpPath,
            'script_path' => $this->scriptPath,
            'task_name' => $this->taskName,
            'schtasks_available' => $this->isSchtasksAvailable(),
            'os' => php_uname('s'),
            'windows' => strtoupper(substr(PHP_OS, 0, 3)) === 'WIN',
            'current_directory' => getcwd(),
            'php_binary' => PHP_BINARY,
            'php_version' => PHP_VERSION,
            'paths_exist' => [
                'php_exists' => file_exists($this->phpPath),
                'script_exists' => file_exists($this->scriptPath)
            ]
        ];
    }
}
?>
