<?php
// CoreFlux/core/CLI/Kernel.php

namespace Core\CLI;

use Core\Database\Connection;
use Exception;
use PDO;
use Core\CLI\Commands\HelpCommand; // Import the HelpCommand class

class Kernel
{
    protected $commands = [];

    public function __construct()
    {
        if (!defined('FS_CONFIG_PATH')) {
             define('FS_CONFIG_PATH', ROOT_PATH . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'config');
        }
        if (!defined('FS_APP_PATH')) {
            define('FS_APP_PATH', ROOT_PATH . DIRECTORY_SEPARATOR . 'app');
        }
        $this->loadCommandsFromManifest();
    }

    protected function loadCommandsFromManifest()
    {
        $manifestPath = FS_CONFIG_PATH . DIRECTORY_SEPARATOR . 'cli_commands.php';

        if (!file_exists($manifestPath)) {
            echo "Error: CLI command manifest not found at '{$manifestPath}'.\n";
            exit(1);
        }

        $commandClasses = require $manifestPath;
        if (!is_array($commandClasses)) {
            echo "Error: CLI command manifest file must return an array of command class names.\n";
            exit(1);
        }

        // --- CRITICAL: Handle the 'help' command separately ---
        // We'll create the HelpCommand instance last, so it has the full list of commands
        $helpCommand = null;
        $tempCommands = [];
        foreach ($commandClasses as $commandClass) {
            if (class_exists($commandClass) && is_subclass_of($commandClass, Command::class)) {
                if ($commandClass === HelpCommand::class) {
                    // Temporarily hold off on creating the HelpCommand
                    $helpCommand = $commandClass;
                } else {
                    $commandInstance = new $commandClass();
                    $tempCommands[] = $commandInstance;
                }
            } else {
                echo "Warning: Command class '{$commandClass}' not found or does not implement " . Command::class . ".\n";
            }
        }
        
        // Register all other commands first
        foreach ($tempCommands as $commandInstance) {
            $this->registerCommand($commandInstance);
        }

        // Now, create and register the HelpCommand, injecting the full list of commands
        if ($helpCommand) {
            $helpInstance = new $helpCommand($this->commands);
            $this->registerCommand($helpInstance);
        }
    }

    public function registerCommand(Command $command)
    {
        $this->commands[$command->getName()] = $command;
    }

    public function run(array $argv)
    {
        $databaseConfig = require FS_CONFIG_PATH . DIRECTORY_SEPARATOR . 'database.php';
        try {
            if (!in_array($databaseConfig['driver'], PDO::getAvailableDrivers())) {
                $availableDrivers = implode(', ', PDO::getAvailableDrivers());
                throw new Exception("PDO driver '{$databaseConfig['driver']}' is not available. Available drivers: [{$availableDrivers}].");
            }
            Connection::init($databaseConfig);
        } catch (Exception $e) {
            echo "Error: " . $e->getMessage() . "\n";
            exit(1);
        }

        $commandName = $argv[1] ?? 'help';
        $args = array_slice($argv, 2);

        if (isset($this->commands[$commandName])) {
            $command = $this->commands[$commandName];
            $exitCode = $command->execute($args);
            exit($exitCode);
        } else {
            // If command is not found, show the help message.
            echo "\nError: Command '{$commandName}' not found.\n";
            $this->commands['help']->execute([]);
            exit(1);
        }
    }

    protected function showHelp()
    {
        echo "\nCoreFlux CLI - Available Commands:\n\n";
        foreach ($this->commands as $command) {
            echo "  " . str_pad($command->getName(), 30) . $command->getDescription() . "\n";
        }
    }
}