<?php
namespace Fifa\ConnectId\Sdk\ExceptionHandler;

use Fifa\ConnectId\Sdk\Api\ApiException;
use Fifa\ConnectId\Sdk\Exception\FifaConnectIdException;
use Fifa\ConnectId\Sdk\ExceptionHandler\Handler\FifaEntityNotFoundHandler;
use Fifa\ConnectId\Sdk\ExceptionHandler\Handler\FifaEntityDeletedHandler;
use Fifa\ConnectId\Sdk\ExceptionHandler\Handler\HandlerInterface;
use Fifa\ConnectId\Sdk\ExceptionHandler\Handler\InvalidClientDataHandler;
use Fifa\ConnectId\Sdk\ExceptionHandler\Handler\TooManyRequestsHandler;
use Fifa\ConnectId\Sdk\ExceptionHandler\Handler\UnauthorizedRequestHandler;

/**
 * Class ApiExceptionHandler
 * @package Fifa\ConnectId\Sdk\ExceptionHandler
 */
class ApiExceptionHandler
{
    /**
     * Creates and returns new FifaConnectIdException.
     * InvalidClientDataHandler, FifaEntityNotFoundHandler, FifaEntityDeletedHandler, UnauthorizedRequestHandler and TooManyRequestsHandler are set up by default.
     *
     * @param ApiException $apiException
     * @param $handlers - objects implementing HandlerInterface
     * @return FifaConnectIdException
     */
    public static function createException(ApiException $apiException, ...$handlers): FifaConnectIdException
    {
        $handlers = array_merge(self::getDefaultHandlers(), array_filter(
            func_get_args(), 
            function($arg) {
                return ($arg instanceof HandlerInterface);
            }
        ));
        
        /** @var HandlerInterface $handler */
        foreach ($handlers as $handler) {
            $e = $handler->handle($apiException);
            if ($e instanceof FifaConnectIdException) {
                return $e;
            }
        }

        return new FifaConnectIdException($apiException);
    }

    /**
     * Returns an array of default exception handlers
     *
     * @return HandlerInterface[]
     */
    private static function getDefaultHandlers(): array
    {
        return array(
            new InvalidClientDataHandler(),
            new FifaEntityNotFoundHandler(),
            new FifaEntityDeletedHandler(),
            new UnauthorizedRequestHandler(),
            new TooManyRequestsHandler()
        );
    }
}