<?php declare(strict_types = 1);

namespace idoit\Module\SyneticsFlows\Automation\Action\PerformExecution;

use idoit\Component\HttpClient;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionInfo\PerformApiCall;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionResult\ErrorApiCallResult;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionResult\ErrorExecutionResult;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionResult\ExecutionResult;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionResult\SuccessApiCallResult;
use idoit\Module\SyneticsFlows\Automation\Execution;

class PerformApiCallExecution implements PerformExecution
{
    public function perform(Execution $execution): ExecutionResult
    {
        $parameters = $execution->getExecution();
        if (!($parameters instanceof PerformApiCall)) {
            return new ErrorExecutionResult('Unsupported execution');
        }
        $client = \isys_application::instance()->container->get('http_client');
        if (!$client instanceof HttpClient) {
            return new ErrorExecutionResult('Cannot perform API call');
        }

        $response = $client->request($parameters->getUrl(), $parameters->getMethod(), [
            'headers' => $parameters->getHeaders(),
            'body' => $parameters->getBody(),
            'query' => $parameters->getQueryParams(),
            'connect_timeout' => 20,
            'timeout' => 20,
        ]);
        $status = $response->getStatusCode();

        if ($status >= 400) {
            return new ErrorApiCallResult($status, $response->getReasonPhrase(), $response->getHeaders());
        }
        $body = $response->getBody()->__toString();
        return new SuccessApiCallResult($status, $body, $response->getHeaders());
    }

    public function supports(Execution $execution): bool
    {
        return $execution->getExecution() instanceof PerformApiCall;
    }
}
