<?php
/**
 * Banker
 *
 * A Caching library implementing psr/cache
 *
 * PHP version 5.6
 *
 * @package     Banker
 * @author      Timothy J. Warren <tim@timshomepage.net>
 * @copyright   2016  Timothy J. Warren
 * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
 * @version     1.0.0
 * @link        https://git.timshomepage.net/timw4mail/banker
 */

namespace Aviat\Banker;

use Psr\Cache\CacheItemInterface;

use Aviat\Banker\Driver\DriverInterface;

/**
 * Base class for Cache items
 */
class Item implements CacheItemInterface {

	/**
	 * The driver for the current cache backend
	 *
	 * @var DriverInterface
	 */
	protected $driver;

	/**
	 * The key of the cache item
	 *
	 * @var string
	 */
	protected $key;

	/**
	 * The expiration time
	 *
	 * @var int | null
	 */
	protected $expiresAt = NULL;

	/**
	 * The time to live
	 *
	 * @var int | null
	 */
	protected $ttl = NULL;

	/**
	 * The value to save in the cache
	 *
	 * @var mixed
	 */
	protected $value;

	/**
	 * Create a Cache Item object
	 *
	 * @param DriverInterface $driver
	 * @param string $key
	 */
	public function __construct(DriverInterface $driver, $key)
	{
		$this->driver = $driver;
		$this->key = $key;
	}

	/**
	 * Returns the key for the current cache item.
	 *
	 * The key is loaded by the Implementing Library, but should be available to
	 * the higher level callers when needed.
	 *
	 * @return string
	 *   The key string for this cache item.
	 */
	public function getKey()
	{
		return $this->key;
	}

	/**
	 * Retrieves the value of the item from the cache associated with this object's key.
	 *
	 * The value returned must be identical to the value originally stored by set().
	 *
	 * If isHit() returns false, this method MUST return null. Note that null
	 * is a legitimate cached value, so the isHit() method SHOULD be used to
	 * differentiate between "null value was found" and "no value was found."
	 *
	 * @return mixed
	 *   The value corresponding to this cache item's key, or null if not found.
	 */
	public function get()
	{
		return $this->driver->get($this->key);
	}

	/**
	 * Confirms if the cache item lookup resulted in a cache hit.
	 *
	 * Note: This method MUST NOT have a race condition between calling isHit()
	 * and calling get().
	 *
	 * @return bool
	 *   True if the request resulted in a cache hit. False otherwise.
	 */
	public function isHit()
	{
		return $this->driver->exists($this->key);
	}

	/**
	 * Sets the value represented by this cache item.
	 *
	 * The $value argument may be any item that can be serialized by PHP,
	 * although the method of serialization is left up to the Implementing
	 * Library.
	 *
	 * @param mixed $value
	 *   The serializable value to be stored.
	 *
	 * @return static
	 *   The invoked object.
	 */
	public function set($value)
	{
		$this->value = $value;
		return $this;
	}

	/**
	 * Sets the expiration time for this cache item.
	 *
	 * @param \DateTimeInterface|null $expiration
	 *   The point in time after which the item MUST be considered expired.
	 *   If null is passed explicitly, a default value MAY be used. If none is set,
	 *   the value should be stored permanently or for as long as the
	 *   implementation allows.
	 *
	 * @return static
	 *   The called object.
	 */
	public function expiresAt($expiration = NULL)
	{
		return $this;
	}

	/**
	 * Sets the expiration time for this cache item.
	 *
	 * @param int|\DateInterval|null $time
	 *   The period of time from the present after which the item MUST be considered
	 *   expired. An integer parameter is understood to be the time in seconds until
	 *   expiration. If null is passed explicitly, a default value MAY be used.
	 *   If none is set, the value should be stored permanently or for as long as the
	 *   implementation allows.
	 *
	 * @return static
	 *   The called object.
	 */
	public function expiresAfter($time = 0)
	{
		$this->ttl = $time;
		return $this;
	}
}