<?php
/**
* 単純なタスクマネージャを実装するクラス
*
* PHP version 5
*
* @package    dispatchers
* @author     stk2k <stk2k@sazysoft.com>
* @copyright  2008 stk2k, sazysoft
*/

class DefaultTaskManager implements ITaskManager
{
	private $_tasks;
	private $_queue;

	/*
	 * コンストラクタ
	 */
	public function __construct()
	{
		$this->_tasks  = NULL;
		$this->_queue  = new EventQueue();
	}

	/*
	 * タスクマネージャ名を取得
	 */
	public function getTaskManagerName()
	{
		return "Default Task Manager";
	}

	/*
	 * タスクマネージャを初期化する
	 */
	public function init( Config $config )
	{
	}

	/*
	 * タスクを取得する
	 */
	public function getTask( $task_name )
	{
		// 作成済みならそれを返す
		if ( isset($this->_tasks[$task_name]) ){
			return $this->_tasks[$task_name];
		}
		// タスクを作成
		$task = Factory::createTask( $task_name );

		// タスクを保存
		$this->_tasks[$task_name] = $task;

		return $task;
	}

	/*
	 * イベントディスパッチを行う
	 *
	 */
	public function dispatchEvents( IRequest $request, $events )
	{
		log_info( "system",  "イベントディスパッチを開始します。", __FILE__, __LINE__ );

		$queue = $this->_queue;

		if ( $events && is_array($events) ){
			foreach( $events as $event_name => $task_name ){
				// タスクの取得
				$task = $this->getTask( $task_name );
				// イベントの作成
				$event = Factory::createEvent( $event_name, $request );
				// イベントをイベントキューに追加
				$queue->enqueue( new EventQueueEntry($task,$event) );
			}
		}

		log_info( "system",  "イベントディスパッチを終了しました。", __FILE__, __LINE__ );
	}

	/**
	 *   イベント処理を行う
	 *
	 */
	public function processEvents( ProcedureContext $context )
	{
		$queue = $this->_queue;

		// 無限ループを避けるため、MAX_EVENT_COUNT以上は処理しない（デフォルトは100回まで）
		$max_event_count = Profile::getInteger( 'MAX_EVENT_COUNT', 100 );

		$event_count = 0;
		while( !$queue->isEmpty() ){
			// イベントを取得
			$entry = $queue->dequeue();
			// ターゲットタスクを取得
			$task = $entry->getTarget();
			// イベントを取得
			$event = $entry->getEvent();
			// イベントを処理
			$result = $task->processEvent( $event, $context );
			// 結果がイベントだったらキューに再追加
			if ( $result instanceof IEvent ){
				$queue->enqueue( $result );
			}
			// イベントカウントのインクリメント
			$event_count ++;
			// イベントカウントが最大を超えていたらワーニングを出して終了
			if ( $event_count > $max_event_count ){
				log_warning( 'system', "イベント処理回数が設定値[$max_event_count]を超えたため、イベント処理を中断しました。", __FILLE__, __LINE__ );
				break;
			}
		}
	}

	/**
	 *   タスクをハンドリングする
	 */
	public function handleTasks()
	{
	}
}
