<?php
namespace ZhiCms\base\cache;
class FileCacheDriver implements CacheInterface{
	protected $config = array();

    public function __construct( $config = array() ) {
		$this->config = array(
								'CACHE_PATH' => 'data/cache/',
								'GROUP' => 'tmp',
								'HASH_DEEP' => 0,								
							);
		$this->config = array_merge($this->config, (array)$config);
    }

    public function get( $key ){
		$content = @file_get_contents( $this->_getFilePath($key) );
		if( empty($content) ) return false;
		
		$expire  =  (int) substr($content, 13, 12);
		if( time() >= $expire ) return false;

		$md5Sign  =  substr($content, 25, 32);
		$content   =  substr($content, 57);
		if( $md5Sign != md5($content) ) return false;
		
		return @unserialize($content);
    }
	

    public function set($key, $value, $expire = 1800){		
        $value = serialize($value);
		$md5Sign = md5($value);
		$expire = time() + $expire;		
        $content    = '<?php exit;?>' . sprintf('%012d', $expire) . $md5Sign . $value;		
       
        $file = $this->_getFilePath($key, true);
        if ($file === false) {
            return false;
        }
        $result = @file_put_contents($file, $content, LOCK_EX);
        return $result !== false;
    }
	
	public function inc($key, $value = 1){
		 return $this->set($key, intval($this->get($key)) + intval($value), -1);
    }
	
	public function des($key, $value = 1){
		 return $this->set($key, intval($this->get($key)) - intval($value), -1);
    }
	
	public function del($key) {
		return @unlink( $this->_getFilePath($key) );
	}
	
    public function clear( $dir='' ) {
        if( empty($dir) ) {
			$dir = $this->config['CACHE_PATH'] . '/' . $this->config['GROUP'] . '/';
			$dir = str_replace('/', DIRECTORY_SEPARATOR, $dir);
		}
		if ( !is_dir($dir) ) return false;

		$handle = opendir($dir);
		while ( ($file = readdir($handle)) !== false ){
			if ( '.' != $file && '..' != $file ){
				is_dir("$dir/$file")? $this->clear("$dir/$file") : @unlink("$dir/$file");
			}
		}
		if ( readdir($handle) == false ){
			closedir($handle);
			@rmdir($dir);
		}
    }
	
	private function _getFilePath($key, $isCreatePath = false){
		$key = md5($key);
		
		$dir = $this->config['CACHE_PATH'] . '/' . $this->config['GROUP'] . '/';
		for($i=0; $i<$this->config['HASH_DEEP']; $i++){
			$dir = $dir. substr($key, $i*2, 2).'/';
		}
		$dir = str_replace('/', DIRECTORY_SEPARATOR, $dir);
		
		if ( !file_exists($dir) ) {
			if ( !@mkdir($dir, 0777, true) ){
				return false;
			 }             
		}
		if ( !is_writable($dir) ) {
			@chmod($dir, 0777);
			if ( !is_writable($dir) ) {
				return false;
			}
		}
		
		return $dir. $key . '.php';
	}
}