<?php

namespace NoahVet\Reef\RabbitMQ\Task\Executor;

use NoahVet\Reef\Domain\Process\SymfonyProcess;
use NoahVet\Reef\Factory\Process\ProcessFactoryInterface;
use NoahVet\Reef\RabbitMQ\Task\ConsoleCommandTask;
use Symfony\Component\Console\Output\OutputInterface;

class NewProcessConsoleTaskCommandExecutor implements ConsoleCommandTaskExecutorInterface
{
    public function __construct(
        private readonly ProcessFactoryInterface $processFactory,
    ) {
    }

    #[\Override]
    public function execute(ConsoleCommandTask $task, ?OutputInterface $output = null): int
    {
        // Prepare process execution
        $process = $this->processFactory->createProcess($this->buildCommandLine($task));
        $process->enableOutput();

        // Start process
        $process->start();

        return $process->wait(static function ($type, $data) use ($output): bool {
            $output?->write($data);

            return true;
        });
    }

    /**
     * @return list<string>
     */
    protected function buildCommandLine(ConsoleCommandTask $task): array
    {
        $commandName = $task->command->getName();
        if (null === $commandName) {
            throw new \LogicException('Command name cannot be null.');
        }

        // Prépare les arguments de la commande dans l'ordre
        $cmdArguments = [];
        foreach ($task->command->getDefinition()->getArguments() as $argument) {
            if (!isset($task->arguments[$argument->getName()])) {
                continue;
            }
            $cmdArguments[] = (string) $task->arguments[$argument->getName()];
        }

        // Ajoute les options
        foreach ($task->arguments as $key => $value) {
            if (!\str_starts_with($key, '--')) {
                continue;
            }
            $cmdArguments[] = $key.'='.$value;
        }

        return \array_merge(
            [
                SymfonyProcess::getPhpBinaryPath(),
                SymfonyProcess::getSymfonyConsolePath(),
                $commandName,
            ],
            $cmdArguments,
        );
    }
}
