<?php
namespace src\Integration;

class DataProvider
{
    private $host;
    private $user;
    private $password;

    /**
     * @param $host
     * @param $user
     * @param $password
     */
    public function __construct($host, $user, $password)
    {
        $this->host = $host;
        $this->user = $user;
        $this->password = $password;
    }
    
    /**
     * @param array $request
     *
     * @return array
     */
    public function get(array $request)
    {
        // returns a response from external service
    }
}

interface CacheInterface
{
    public function get(array $input);

    public function set(CacheItemInterface $cacheItem, array $value, \DateTime $expireAt = null);
}

class Cache implements CacheInterface
{
    private $cache;

    public function __construct(CacheItemPoolInterface $cache)
    {
        $this->cache = $cache;
    }

    protected function getCacheKey(array $input)
    {
        return json_encode($input);
    }

    public function get(array $input)
    {
        $cacheKey = $this->getCacheKey($input);
        $cacheItem = $this->cache->getItem($cacheKey);
        return $cacheItem;
    }

    public function set(CacheItemInterface $cacheItem, array $value, \DateTime $expireAt = null)
    {
        $cacheItem->set($value);

        if (null !== $expiresAt) {
            $cacheItem->expiresAt($expiresAt);
        }
    }
}

namespace src\Decorator;

use DateTime;
use Exception;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Log\LoggerInterface;
use src\Integration\DataProvider;

class DecoratorManager
{
    private $cache;
    private $logger;
    private $provider;

    */
    * @param CacheItemPoolInterface $cache
    */
    public function __construct(DataProvider $provider, LoggerInterface $logger, CacheInterface $cache)
    {
        $this->provider = $provider;
        $this->logger = $logger;
        $this->cache = $cache;
    }

    /**
     * {@inheritdoc}
     */
    public function getResponse(array $input)
    {
        try {
            $cacheItem = $this->cache->get($input);
            if ($cacheItem->isHit()) {
                return $cacheItem->get();
            }

            $result = $this->provider->get($input);

            $this->cache
                ->set($cacheItem, $result, (new DateTime())->modify('+1 day'));

            return $result;
        } catch (Exception $e) {
            $this->logger->critical('Error');
        }

        return [];
    }
}