<?php
/**
 * CLI ядро системи Flowaxy CMS
 * Обробляє CLI команди (без зайвих команд — тільки системні адміністративні утиліти)
 *
 * @package Flowaxy\Core\System\Kernel
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Core\System\Kernel;

use Flowaxy\Core\System\Container\CoreServiceProvider;
use Flowaxy\Interface\CLI\CommandInterface;
use Flowaxy\Interface\CLI\Commands\CacheClearCommand;
use Flowaxy\Interface\CLI\Commands\ConfigDeleteCommand;
use Flowaxy\Interface\CLI\Commands\ConfigGetCommand;
use Flowaxy\Interface\CLI\Commands\ConfigListCommand;
use Flowaxy\Interface\CLI\Commands\ConfigShowCommand;
use Flowaxy\Interface\CLI\Commands\ConfigSetCommand;
use Flowaxy\Interface\CLI\Commands\LogsClearCommand;
use Flowaxy\Interface\CLI\Commands\RootPasswordCommand;
use Flowaxy\Interface\CLI\Commands\ScssCompileCommand;
use Flowaxy\Interface\CLI\Commands\PreloadGenerateCommand;
use Flowaxy\Interface\CLI\Commands\TestRunCommand;

use function array_slice;
use function count;

final class CliKernel extends Kernel
{
    /**
     * @var array<int, string>
     */
    private array $argv = [];

    /**
     * @var array<string, CommandInterface>
     */
    private array $commands = [];

    /**
     * @param string $rootDir Корінь проекту
     * @param array<int, string> $argv Аргументи CLI
     */
    public function __construct(string $rootDir, array $argv = [])
    {
        parent::__construct($rootDir);
        $this->argv = $argv;
        $this->registerCommands();
    }

    protected function getServiceProviders(): array
    {
        return [
            CoreServiceProvider::class,
        ];
    }

    public function serve(): void
    {
        if (! $this->isBooted()) {
            $this->boot();
            $this->configure();
            $this->registerProviders();
            $this->bootProviders();
        }

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

        if ($commandName === 'help' || $commandName === '--help' || $commandName === '-h') {
            $this->showHelp();
            return;
        }

        $command = $this->commands[$commandName] ?? null;
        if (! $command) {
            $this->line("Unknown command: {$commandName}");
            $this->line('');
            $this->showHelp();
            exit(1);
        }

        $exitCode = $command->execute($args);
        exit($exitCode);
    }

    private function registerCommands(): void
    {
        $this->register(new RootPasswordCommand());

        $this->register(new ConfigListCommand());
        $this->register(new ConfigShowCommand());
        $this->register(new ConfigGetCommand());
        $this->register(new ConfigSetCommand());
        $this->register(new ConfigDeleteCommand());

        $this->register(new CacheClearCommand());
        $this->register(new LogsClearCommand());

        $this->register(new ScssCompileCommand());
        $this->register(new PreloadGenerateCommand());
        $this->register(new TestRunCommand());
    }

    private function register(CommandInterface $command): void
    {
        $this->commands[$command->getName()] = $command;
    }

    private function showHelp(): void
    {
        $this->line('Flowaxy CLI');
        $this->line('Usage: php index.php <command> [args]');
        $this->line('');
        $this->line('Commands:');

        foreach ($this->commands as $name => $command) {
            $desc = $command->getDescription();
            $this->line("  - {$name}" . ($desc !== '' ? "  {$desc}" : ''));
        }

        $this->line('');
        $this->line("Help: php index.php <command> --help");
    }

    private function line(string $message): void
    {
        echo $message . "\n";
    }
}
