<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * Run active tasks according to their CRON schedule
 *
 * @package    Task
 * @category   Tasks
 * @author     Deon George
 * @copyright  (c) 2009-2013 Open Source Billing
 * @license    http://dev.osbill.net/license.html
 */
class Task_Task_Run extends Minion_Task {
	protected $_options = array(
		'id'=>NULL,
		'force'=>FALSE, 
		'verbose'=>FALSE,
	);

	protected function _execute(array $params) {
		if ($params['id']) {
			$to = ORM::factory('Task',$params['id']);

			if ($to->loaded()) {
				if (! $to->status)
					throw new Minion_Exception_InvalidTask('Task :task (:name) NOT active',array(':task'=>$params['id'],':name'=>$to->name));

				Kohana::$config->load('debug')->task_sim ? printf("Would Run task: (%s) %s\n",$to->id,$to->name) : $this->_run($to,$params['force'],$params['verbose']);

			} else
				throw new Minion_Exception_InvalidTask('Unknown task :task',array(':task'=>$params['id']));

		} else {
			$t = time();

			foreach (ORM::factory('Task')->list_active() as $to)
				if ($to->next_run() < $t)
					Kohana::$config->load('debug')->task_sim ? printf("Would Run task: (%s) %s\n",$to->id,$to->name) : $this->_run($to);
		}
	}

	private function _run(Model_Task $to,$force=FALSE,$verbose=FALSE) {
		if ($verbose)
			printf("Running Task: %s\n",$to->id);

		$r = rand(0,9999);
		$tlo = ORM::factory('Task_Log');
		$tlo->task_id = $to->id;

		if ($to->running AND ! $force)
			$tlo->message = sprintf('Task %s is already running',$to->id);

		else {
			try {
				// Get a lock
				$to->running = 1;
				$to->running_host = $r;
				$to->save();

				// Check we are the winning host to run this task
				// @todo We need to test that the lock is not stale
				$to->reload();
				if ($to->running_host != $r)
					return;

				switch ($to->type) {
					case 1:
						ob_start();
						Minion_Task::factory(array('site'=>Minion_CLI::options('site'),'task'=>$to->command))->execute();
						$r = ob_get_clean();
						$to->running = 0;
						$to->running_host = NULL;

						$tlo->message = $r;
						$tlo->result = 0;

						break;
					case 0:
						$r = Request::factory($to->command)->execute();

						if ($r->status() == 200) {
							$to->running = 0;
							$to->running_host = NULL;
						}

						$tlo->message = $r->body();
						$tlo->result = $r->status();

						break;

					default:
						throw new Kohana_Exception('Unknown task type :type',array(':type'=>$to->type));
				}

				// Clear our lock and update the last run time
				$to->date_run = time();


			} catch (Exception $e) {
				$tlo->result = $e->getCode();
				$tlo->message = Kohana_Exception::text($e);

				$to->running = 1;
				$to->running_host = 'ERROR';
			}

			$to->save();
		}

		if ($verbose)
			printf("Message: %s\n",$tlo->message);

		if ($to->log)
			$tlo->save();
	}
}
?>
