<?php
/**
 * @copyright NetMonsters <team@netmonsters.ru>
 * @link http://netmonsters.ru
 * @package Majestic
 * @subpackage Cache
 * @since 2010-03-04
 */

class MemcacheCache extends Cache
{

    /**
     * @var Memcache
     */
    protected $connection = null;

    /**
     * @var null|string
     */
    protected $key_salt = null;

    /**
     * One hour to live default
     *
     * @var int
     */
    protected $expire = 3600;

    public function __construct($config)
    {
        $this->connection = new Memcache();

        if (isset($config['key_salt'])) {
            $this->key_salt = $config['key_salt'];
            unset($config['key_salt']);
        }

        $required = array('hostname', 'port');
        foreach ($config as $c) {
            foreach ($required as $option) {
                if (!isset($c[$option])) {
                    throw new InitializationException('Configuration must have a "' . $option . '".');
                }
            }
            $this->connection->addServer($c['hostname'], $c['port']);
        }
    }

    /**
     * Add an item to the cache
     *
     * @param string $key
     * @param mixed $value
     * @param int $expire
     * @return bool
     */
    public function add($key, $value, $expire = 0)
    {
        return $this->connection->add($this->getKey($key), $value, null, $this->getExpire($expire));
    }

    /**
     * Decrement item's value
     *
     * @param string $key
     * @param int $decrement
     * @return bool
     */
    public function decrement($key, $decrement = 1)
    {
        return $this->connection->decrement($this->getKey($key), $decrement);
    }

    /**
     * Delete item from the cache
     *
     * @param string $key
     * @internal param int $value
     * @return bool
     */
    public function del($key)
    {
        return $this->connection->delete($this->getKey($key), 0);
    }

    /**
     * Flush all existing items
     *
     * @return bool
     */
    public function flush()
    {
        return $this->connection->flush();
    }

    /**
     * Retrieve item from the cache
     *
     * @param string $key
     * @return mixed
     */
    public function get($key)
    {
        return $this->connection->get($this->getKey($key));
    }

    /**
     * Increment item's value
     *
     * @param string $key
     * @param int $increment
     * @return bool
     */
    public function increment($key, $increment = 1)
    {
        return $this->connection->increment($this->getKey($key), $increment);
    }

    /**
     * Replace value of the existing item
     *
     * @param string $key
     * @param mixed $value
     * @param int $expire
     * @internal param mixed $var
     * @return bool
     */
    public function replace($key, $value, $expire = 0)
    {
        return $this->connection->replace($this->getKey($key), $value, null, $this->getExpire($expire));
    }

    /**
     * Store data in the cache
     *
     * @param string $key
     * @param mixed $value
     * @param int $expire
     * @return bool
     */
    public function set($key, $value, $expire = 0)
    {
        return $this->connection->set($this->getKey($key), $value, null, $this->getExpire($expire));
    }

    /**
     * @param string $key
     * @return string
     */
    protected function getKey($key)
    {
        return md5($this->key_salt . $key);
    }

    public function getExpire($expire)
    {
        return ($expire > 0) ? $expire : $this->expire;
    }
}