<?php
class LiveBehavior extends ModelBehavior {

	private $config = array();


# ~ Constructor  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function setup(Model $Model, $config = array()) {
		$config['search'] = APP . "{$config['folder']}/*.{$config['extension']}";
		$this->config[$Model->alias] = $config;
		$this->config[$Model->alias]['refreshed'] = false;
	}


# ~ Refresh database on every query  - - - - - - - - - - - - - - - - - - - - - #
	public function beforeFind(Model $Model, $query) {
		$Model->refreshLive($Model);
		return $query;
	}


# ~ Refresh the database state - - - - - - - - - - - - - - - - - - - - - - - - #
	public function refreshLive(Model &$Model, $wtf = false, $force = false) {
		$return = null;

		# Only one refresh per request
		if($this->config[$Model->alias]['refreshed']) return;
		$this->config[$Model->alias]['refreshed'] = true;

		Timer::start("Refresh live model: {$Model->alias}"); {

			# Read all files
			$found = glob($this->config[$Model->alias]['search']);

			# Check cache
			$total = '';
			$cache = Cache::read($Model->alias, 'live');
			if(!empty($found)) foreach($found as $file) {
				$total .= file_get_contents($file);
			}
			$hash = md5($total);

			if(!$force && $cache == $hash) {
				$return = true;

			} else {

				# Update cache
				$Model->invalidateCache();
				Cache::write($Model->alias, $hash, 'live');

				# Create list of entities
				foreach((array)$found as $file) {
					if(preg_match('~/(?P<id>\d+)-(?P<name>.*)\.[a-z]+$~ U', $file, $match)) {

						# Make sure there is no overlapping
						if(isset($entities[$match['id']])) {
							throw new CakeException("{$Model->alias} live model has two entities with id={$match['id']}");
						}

						# Append to queue
						$name = Sanitize::escape(str_replace('_', ' ', basename($match['name'])));
						$live = Sanitize::escape(file_get_contents($file));
						$query[] = "({$match['id']}, '{$name}', '{$live}', Now())";
					}
				}

				# Update tables
				if(!empty($query)) {
					$live = $this->config[$Model->alias]['field'];
					$query = "
						INSERT `{$Model->tablePrefix}{$Model->useTable}`
						(`{$Model->primaryKey}`, `name`, `{$live}`, `modified`) VALUES " .
						implode(',', $query) . "
						ON DUPLICATE KEY UPDATE `name` = Values(`name`), `{$live}` = Values(`{$live}`)";
					$Model->$query();
				}

				# Remove generated js
				cleanDir(WWW_ROOT . 'generated/');
			}

		} Timer::end("Refresh live model: {$Model->alias}");

		if($return !== null) {
			return $return;
		}
	}

}
