<?php
/*
* @package LabCMS
* @copyright (c) 2006 Alexander Levin aka Loki (loki_angel@mail.ru)
* @support http://labcms.ru
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/

if (!defined("PATH_SEPARATOR"))
  define("PATH_SEPARATOR", getenv("COMSPEC")? ";" : ":");
ini_set("include_path", ini_get("include_path").PATH_SEPARATOR.dirname(__FILE__));

class TCache
{
	private static $_cache=null;
	private static $type='file';
	private static $host_id='';
	
	private static function i()
	{
		self::$type=config::get('core.use_memcached')?"memcache":"file";
		
		if (self::$_cache[self::$type]) {
			return self::$_cache[self::$type];
		}
		
		self::$host_id=Config::Get('core.host_id');
		
		switch(self::$type)
		{
			case('memcache'):
				if (!class_exists('Memcache')) {
					return 'Класс Memcache не найден! Кэширование отключено';
				}
				$options=array(
					'compression'=>config::get('core.memcached_compress'),
					'servers'=>array(
						'host'=>config::get('core.memcached_host'),
						'port'=>config::get('core.memcached_port'),
						'persistent'=>true 
					)
				);
				
				$cache = new Dklab_Cache_Backend_MemcachedMultiload($options);
				self::$_cache[self::$type]=new Dklab_Cache_Backend_TagEmuWrapper($cache);
				
				break;
			case('file'):
				$options=array('cacheDir' => LAB_PATH_DATA.'/cache/tagged/', 'automaticSerialization' => true);
				$cache = new Cache_ZendAdapter($options);
				self::$_cache[self::$type]=new Dklab_Cache_Backend_TagEmuWrapper($cache);
				break;
		}
		
		if (rand(1, 100)==50) {			
			self::$_cache[self::$type]->Clean(Zend_Cache::CLEANING_MODE_OLD);			
		}

		return self::$_cache[self::$type];
	}
	
	public static function get($key)
	{
		if (!config::get('core.cache')) return false;
		
		if (is_array($key))  return self::multiGet($key);
		
		$data=self::i()->load(self::_getKey($key));
		if ('file'==self::$type && $data!==false) {
			return unserialize($data);
		} else {
			return $data;
		}
	}
	
	public static function multiGet($keys)
	{
		if ('file'==self::$type) {
			$result=array();
			foreach ($keys as $key=>$val) {
				if (false !== ($data = self::Get($val))) {
					$result[$key]=$data;
				}
			}
			if (count($result)>0) {
				return $result;
			}
			return false;
		} elseif ('memcache'==self::$type) {
			$hKeys=self::_getKey($keys);
			$result=parent::get($hKeys);
			if ($result) {
				foreach ($hKeys as $id=>$hKey) {
					if (isset($result[$hKey])) {
						$result[$keys[$id]]=$result[$hKey];
						unset($result[$hKey]);
					}
				}
			}
		}
	}
	
	public static function set($data, $key, $tags=array(), $lifeTime=false)
	{
		if (!config::get('core.cache')) return false;
		$key=md5(Config::Get('core.host_id').$key);
		if ('file'==self::$type) {
			$data=serialize($data);
		}
		return self::i()->save($data, $key, $tags, $lifeTime);
	}
	
	public static function remove($key)
	{
		if (is_array($key)) {
			foreach ($key as $v) {
				self::remove($v);
			}
			return;
		}
		$key=md5(Config::Get('core.host_id').$key);
		return self::i()->remove($key);
	}
	
	public static function clean($mode = 'ALL', $tags = array())
	{
		switch($mode) {
			case('ALL'):
				$mode=Zend_Cache::CLEANING_MODE_ALL;
				break;
			case('OLD'):
				$mode=Zend_Cache::CLEANING_MODE_OLD;
				break;
			case('MATCH_TAG'):
				$mode=Zend_Cache::CLEANING_MODE_MATCHING_TAG;
				break;
			case('NOT_MATCH_TAG'):
				$mode=Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG;
				break;
		}
		return self::i()->clean($mode, $tags);
	}
	
	protected static function _getObject()
	{
		return self::i();
	}
	
	protected static function _getKey($key)
	{
		if (!is_array($key)) return md5(self::$host_id.$key);
		foreach ($key as $k=>$v) {
			$key[$k]=md5(self::$host_id.$v);
		}
		return $key;
	}
}