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

/**
 * OSB Application Module Method Token Model
 *
 * @package    OSB
 * @category   Models
 * @author     Deon George
 * @copyright  (c) 2009-2013 Open Source Billing
 * @license    http://dev.osbill.net/license.html
 */
class Model_Module_Method_Token extends ORM_OSB {
	// This module doesnt keep track of column updates automatically
	protected $_updated_column = FALSE;

	// Relationships
	protected $_belongs_to = array(
		'account'=>array(),
		'module_method'=>array('foreign_key'=>'method_id'),
	);
	protected $_has_one = array(
		'record_id'=>array(),
	);

	public function method(array $modmeth) {
		list($module,$method) = $modmeth;

		if (! $method instanceof Model_Module_Method) {
			if (is_numeric($module))
				$mo = ORM::factory('Module',$module);
			elseif (is_string($module))
				$mo = ORM::factory('Module',array('name'=>$module));
			elseif (! $module instanceof Model_Module)
				throw new Kohana_Exception('Unknown module :module',array(':module'=>serialize($module)));
			else
				$mo = $module;

			if (! $mo->loaded())
				throw new Kohana_Exception('Unknown module :module - not loaded?',array(':module'=>$mo->id));

			if (is_numeric($method))
				$mmo = ORM::factory('Module_Method',$method);
			elseif (is_string($method))
				$mmo = ORM::factory('Module_Method',array('name'=>$method,'module_id'=>$mo->id));
			else
				throw new Kohana_Exception('Unknown method :method',array(':method'=>serialize($method)));
		} else
			$mmo = $method;

		if (! $mmo->loaded())
			throw new Kohana_Exception('Unknown method :method - not loaded?',array(':method'=>$mmo->id));

		$this->method_id = $mmo->id;

		return $this;
	}

	public function account($account) {
		if (! $account instanceof Model_Account) {
			if (is_numeric($account))
				$ao = ORM::factory('Account',$account);
			else
				throw new Kohana_Exception('Unknown account :account',array(':account'=>serialize($account)));
		} else
			$ao = $account;

		$this->account_id = $ao->id;

		return $this;
	}

	public function uses($uses) {
		$this->uses = $uses;

		return $this;
	}

	public function expire($expire) {
		$this->date_expire = $expire;

		return $this;
	}

	// @todo Login Reset: When called within a timelimit (so existing token already exists), is returning true but password reset emails have blanks where the tokens are
	public function generate() {
		if (! $this->account_id OR ! $this->method_id OR ! ($this->date_expire OR $this->uses))
			return NULL;

		// Check we dont already have a valid token
		$mmto = ORM::factory('Module_Method_Token')
			->where('account_id','=',$this->account_id)
			->where('method_id','=',$this->method_id)
			->find();

		if ($mmto->loaded()) {
			// Check that the token is still good
			if ((is_null($mmto->date_expire) OR $mmto->date_expire > time()) AND (is_null($mmto->uses) OR $mmto->uses > 0)) {
				$this->token = $mmto->token;
				return $this->token;

			// Token expired
			} else
				$mmto->delete();
		}

		$this->token = md5(sprintf('%s:%s:%s',$this->account_id,$this->method_id,time()));
		$this->save();

		return $this->saved() ? $this->token : NULL;
	}
}
?>
