<?php

namespace Velis\Cache;

use Phalcon\Cache\Adapter\AdapterInterface;
use Psr\SimpleCache\CacheInterface as PsrCacheInterface;
use Velis\Arrays;

/**
 * Redis cache
 *
 * @author Jan Małysiak <jan.malysiak@velis.pl>
 */
class RedisCache extends AbstractCache
{
    private array $buffer = [];

    private AdapterInterface $adapter;

    /**
     * @param \Phalcon\Proxy\Psr16\Cache|\Phalcon\Cache $implementation
     * @param $debug
     */
    public function __construct(PsrCacheInterface $implementation, $debug = false)
    {
        parent::__construct($implementation, $debug);

        $this->adapter = $implementation->getAdapter();
    }

    /**
     * {@inheritDoc}
     */
    public function get($key, $default = null)
    {
        // Get value from buffer if it's another call for the same key
        // and exclude this call from profiler
        if (array_key_exists($key, $this->buffer)) {
            return $this->buffer[$key];
        }

        $this->initializeProfiler($key, __FUNCTION__);

        $result = null;

        if ($this->implementation->has($key)) {
            $result = $this->implementation->get($key, $default);
            $result = $this->filterEmptyArray($result);
            $this->buffer[$key] = $result;
        }

        $this->concludeProfiler($key);

        return $result;
    }

    /**
     * {@inheritDoc}
     */
    public function set($key, $value, $ttl = null)
    {
        $this->initializeProfiler($key, __FUNCTION__);
        $dataToSet = $value;

        if (is_array($dataToSet) && empty($dataToSet)) {
            $dataToSet = Arrays::NULL_ARRAY;
        }

        $result = $this->implementation->set($key, $dataToSet, $ttl);
        $this->buffer[$key] = $value;

        $this->concludeProfiler($key);

        return $result;
    }

    /**
     * {@inheritDoc}
     */
    public function offsetUnset($offset): void
    {
        unset($this->buffer[$offset]);
        parent::offsetUnset($offset);
    }

    /**
     * Unsets buffer for $key (whole buffer when $key == null)
     * @param string|null $key
     */
    public function unsetBuffer($key = null)
    {
        if (!$key) {
            $this->buffer = [];
        } else {
            unset($this->buffer[$key]);
        }
    }

    /**
     * {@inheritDoc}
     */
    public function getKeys(string $prefix = ''): array
    {
        return $this->adapter->getKeys($prefix);
    }
}
