#!/usr/bin/env php
<?php

declare(strict_types=1);

use Fennec\Autoload\Autoloader;
use Fennec\Clock\SystemClock;
use Fennec\Console\CommandNotFoundException;
use Fennec\Console\CommandRegistry;
use Fennec\Console\Command\KeyGenerateCommand;
use Fennec\Console\Command\LogCleanCommand;
use Fennec\Console\Command\MakeCommandCommand;
use Fennec\Console\Command\RouteCacheCommand;
use Fennec\Console\Command\RouteListCommand;
use Fennec\Console\ConsoleOutput;
use Fennec\Container\Container;
use Fennec\Reflection\DirectoryClassFinder;
use Fennec\Routing\RouteCache;
use Fennec\Routing\RouteScanner;

require dirname(__DIR__) . '/fennec/src/Autoload/Autoloader.php';

$rootPath = dirname(__DIR__);

$autoloader = new Autoloader();
$autoloader->addNamespace('Fennec\\', $rootPath . '/fennec/src');
$autoloader->addNamespace('App\\', $rootPath . '/src');
$autoloader->register();

$container = new Container();

$container->bind(RouteCache::class, static fn (): RouteCache => new RouteCache($rootPath . '/var/cache/routes.php'));

$container->bind(RouteCacheCommand::class, static fn (Container $c): RouteCacheCommand => new RouteCacheCommand(
    $c->get(RouteScanner::class),
    $c->get(RouteCache::class),
    $c->get(ConsoleOutput::class),
    'App\\Controller',
    $rootPath . '/src/Controller',
));

$container->bind(RouteListCommand::class, static fn (Container $c): RouteListCommand => new RouteListCommand(
    $c->get(RouteScanner::class),
    $c->get(ConsoleOutput::class),
    'App\\Controller',
    $rootPath . '/src/Controller',
));

$container->bind(LogCleanCommand::class, static fn (Container $c): LogCleanCommand => new LogCleanCommand(
    $c->get(ConsoleOutput::class),
    new SystemClock(),
    $rootPath . '/var/logs',
));

$container->bind(MakeCommandCommand::class, static fn (Container $c): MakeCommandCommand => new MakeCommandCommand(
    $c->get(ConsoleOutput::class),
    $rootPath . '/src/Console/Command',
    'App\\Console\\Command',
));

$container->bind(KeyGenerateCommand::class, static fn (Container $c): KeyGenerateCommand => new KeyGenerateCommand(
    $c->get(ConsoleOutput::class),
    $rootPath . '/.env.local',
));

$registry = new CommandRegistry($container, new DirectoryClassFinder());
$registry->discover('Fennec\\Console\\Command', $rootPath . '/fennec/src/Console/Command');
$registry->discover('App\\Console\\Command', $rootPath . '/src/Console/Command');

$arguments = $argv;
\array_shift($arguments);
$commandName = \array_shift($arguments);

$output = new ConsoleOutput();

if ($commandName === null) {
    $output->info('Commandes disponibles :');

    foreach ($registry->all() as $command) {
        $output->info(\sprintf('  %-20s %s', $command->getName(), $command->getDescription()));
    }

    exit(0);
}

try {
    $command = $registry->get($commandName);
    exit($command->execute($arguments));
} catch (CommandNotFoundException $e) {
    $output->error($e->getMessage());
    exit(1);
}
