<?php

declare(strict_types=1);

namespace core\handler;

use TypeError;
use Traversable;
use utils\Command;
use utils\CommandInterface;
use utils\type\CommandType;

final class RetrieveArrayHandler extends AbstractHandler
{
    private const REQUIRED_ARGUMENTS_COUNT = 1;

    public function process(CommandInterface $command): CommandInterface
    {
        $this->validate($command, self::REQUIRED_ARGUMENTS_COUNT, self::class);

        $response = $command->getPayload()[0];
        $runtimeName = $command->getRuntimeName();

        if (is_array($response)) {
            return new Command($runtimeName, CommandType::ARRAY(), $response);
        }

        if (is_string($response)) {
            $unpacked = unpack('C*', $response);
            if ($unpacked === false) {
                throw new TypeError('Invalid argument type for RetrieveArrayHandler. Expected an array.');
            }

            return new Command($runtimeName, CommandType::ARRAY(), array_values($unpacked));
        }

        if ($response instanceof Traversable) {
            return new Command($runtimeName, CommandType::ARRAY(), iterator_to_array($response));
        }

        throw new TypeError('Invalid argument type for RetrieveArrayHandler. Expected an array.');
    }
}
