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

/**
 *
 * @package    PTA
 * @subpackage Nodes
 * @category   Models
 * @author     Deon George
 * @copyright  (c) 2010 phpTSMadmin Development Team
 * @license    http://phptsmadmin.sf.net/license.html
 */
class Model_NODE extends TSM_ORM {
	protected $_table_name = 'NODES';
	protected $_primary_key = 'NODE_NAME';
	protected $_sorting = array(
		'NODE_NAME'=>'ASC',
	);

	protected $_has_one = array(
		'DOMAIN'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME'),
	);
	protected $_has_many = array(
		'FILESPACE'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODE_NAME'),
		'VOLUMEUSAGE'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODE_NAME'),
		'ASSOCIATION'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODE_NAME'),
		'MGMTCLASS'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME'),
		'CLIENTOPT'=>array('foreign_key'=>'OPTIONSET_NAME','far_key'=>'OPTION_SET'),
		'SUMMARY'=>array('foreign_key'=>'ENTITY','far_key'=>'NODE_NAME'),
		'EVENT'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODE_NAME'),
		'OCC'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODE_NAME'),
	);

	protected $_tsm = array(
		'db2'=>array(
			'_primary_key'=>'NODENAME',
			'_sorting'=>array(
				'NODENAME'=>'ASC',
			),
			'_has_one'=>array(
				'DOMAIN'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAINNAME'),
			),
			'_has_many'=>array(
				'FILESPACE'=>array('foreign_key'=>'NODEID','far_key'=>'NODEID'),
				'VOLUMEUSAGE'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODENAME'),
				'ASSOCIATION'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODENAME'),
				'MGMTCLASS'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME'),
				'CLIENTOPT'=>array('foreign_key'=>'OPTIONSET_NAME','far_key'=>'OPTIONSET'),
				'SUMMARY'=>array('foreign_key'=>'ENTITY','far_key'=>'NODENAME'),
				'EVENT'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODENAME'),
				'OCC'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODENAME'),
			),
			'translate'=>array(
				'NODE_NAME'=>'NODENAME',
				'CLIENT_VERSION'=>'CLNTVERSION',
				'CLIENT_RELEASE'=>'CLNTRELEASE',
				'CLIENT_LEVEL'=>'CLNTLEVEL',
				'CLIENT_SUBLEVEL'=>'CLNTSUBLEVEL',
				'PLATFORM_NAME'=>'OSNAME',
				'CLIENT_OS_LEVEL'=>'CLNTOSLEVEL',
				'LASTACC_TIME'=>'LACDATE',
				'REG_TIME'=>'REGDATE',
				'PWSET_TIME'=>'PWSETDATE',
				'LASTSESS_SENT'=>'SESSSENT',
				'LASTSESS_RECVD'=>'SESSRECVD',
				'LASTSESS_DURATION'=>'SESSDURATION',
				'LASTSESS_IDLEWAIT'=>'SESSIDLEWAIT',
				'LASTSESS_COMMWAIT'=>'SESSCOMMWAIT',
				'LASTSESS_MEDIAWAIT'=>'SESSMEDIAWAIT',
				'TCP_ADDRESS'=>NULL,
				'EMAIL_ADDRESS'=>NULL,
				'REG_ADMIN'=>'REGISTRAR',
				'PASSEXP'=>NULL,
				'INVALID_PW_COUNT'=>'INVPWCOUNT',
				'LOCKED'=>'LOCKSTATE',
				'DOMAIN_NAME'=>'DOMAINNAME',
				'OPTION_SET'=>'OPTIONSET',
				'COLLOCGROUP_NAME'=>NULL,
				'COMPRESSION'=>'COMPRESS',
				'ARCHDELETE'=>'ARCHDEL',
				'BACKDELETE'=>'BACKDEL',
				'KEEP_MP'=>NULL,
				'MAX_MP_ALLOWED'=>'MAXNUMMP',
			),
		),
	);

	protected $_display_filters = array(
		'REG_TIME'=>array(
			array('TSM_ORM::date',array(':value','d-M-Y')),
		),
		'PWSET_TIME'=>array(
			array('TSM_ORM::date',array(':value','d-M-Y')),
		),
		'LASTACC_TIME'=>array(
			array('TSM_ORM::date',array(':value','d-M-Y')),
		),
		'LASTSESS_SENT'=>array(
			array('number_format',array(':value',0)),
		),
		'LASTSESS_RECVD'=>array(
			array('number_format',array(':value',0)),
		),
		'LASTSESS_DURATION'=>array(
			array('number_format',array(':value',2)),
		),
		'LASTSESS_IDLEWAIT'=>array(
			array('number_format',array(':value',2)),
		),
		'LASTSESS_COMMWAIT'=>array(
			array('number_format',array(':value',2)),
		),
		'LASTSESS_MEDIAWAIT'=>array(
			array('number_format',array(':value',2)),
		),
	);

	/**
	 * Get all the FILESPACES for this NODE
	 */
	private function _filespaces() {
		$result = array();

		// In the interest of performance, we load all the records and get PHP to process it.
		// Our ORM caching we reduce the hit on TSM.
		foreach (ORM::factory('FILESPACE')->find_all() as $o)
			if ($o->NODE_NAME == $this->NODE_NAME)
				array_push($result,$o);

		return $result;
	}

	/**
	 * Get all the OCCUPANCY for this NODE
	 */
	private function _occupancy() {
		$result = array();

		// In the interest of performance, we load all the records and get PHP to process it.
		// Our ORM caching we reduce the hit on TSM.
		foreach (ORM::factory('OCC')->find_all() as $o)
			if ($o->NODE_NAME == $this->NODE_NAME)
				array_push($result,$o);

		return $result;
	}

	/**
	 * Get all the VOLUMES for this NODE
	 */
	private function _volumeusage() {
		$result = array();

		// In the interest of performance, we load all the records and get PHP to process it.
		// Our ORM caching we reduce the hit on TSM.
		foreach (ORM::factory('VOLUMEUSAGE')->find_all() as $o)
			if ($o->NODE_NAME == $this->NODE_NAME)
				array_push($result,$o);

		return $result;
	}

	public function fs() {
		return $this->_filespaces();
	}

	/**
	 * Return the version of the TSM client
	 */
	public function version() {
		if ($this->CLIENT_VERSION)
			return sprintf('%s.%s.%s.%s',$this->CLIENT_VERSION,$this->CLIENT_RELEASE,$this->CLIENT_LEVEL,$this->CLIENT_SUBLEVEL);
		else
			return '';
	}

	/**
	 * Return the OS version for the TSM client
	 */
	public function platform() {
		return sprintf('%s %s',$this->PLATFORM_NAME,$this->CLIENT_OS_LEVEL ? '('.$this->CLIENT_OS_LEVEL.')' : '');
	}

	// @todo This needs to return the global configuration.
	public function passexp() {
		if ($this->PASSEXP)
			return 'TBA';
		else
			return _('No Set');
	}

	// @todo This needs to be validated as a correct calculation
	public function lasttransferpercent() {
		$x = 100-($this->LASTSESS_IDLEWAIT+$this->LASTSESS_COMMWAIT+$this->LASTSESS_MEDIAWAIT);
		return $x < 0 ? 0 : $x;
	}

	// @todo This needs to be validated as a correct calculation
	public function lasttransfertime() {
		if ($this->LASTSESS_DURATION)
			return $this->LASTSESS_DURATION*($this->lasttransferpercent()/100);
		else
			return 0;
	}

	// @todo This needs to be validated as a correct calculation
	public function lastsendperformance() {
		if ($this->lasttransfertime())
			return $this->LASTSESS_SENT/$this->lasttransfertime()/1024/1024;
		else
			return 0;
	}

	// @todo This needs to be validated as a correct calculation
	public function lastreceiveperformance() {
		if ($this->lasttransfertime())
			return $this->LASTSESS_RECVD/$this->lasttransfertime()/1024/1024;
		else
			return 0;
	}

	/**
	 * The last sent aggregate performance
	 */
	public function lastsendaggperformance() {
		if ((real)$this->LASTSESS_DURATION)
			return $this->LASTSESS_SENT/$this->LASTSESS_DURATION/1024/1024;
		else
			return 0;
	}

	/**
	 * The last receive aggregate performance
	 */
	public function lastreceiveaggperformance() {
		if ((real)$this->LASTSESS_DURATION)
			return $this->LASTSESS_RECVD/$this->LASTSESS_DURATION/1024/1024;
		else
			return 0;
	}

	// @todo This should return the system setting (cloptset), if the node setting is not configured.
	public function txngroupmax() {
		return $this->TXNGROUPMAX;
	}

	// Test to see if a node has any data of type
	// @param $type is BACKUP/ARCHIVE/SPACE MANAGED
	public function hasData($type) {
		return $this->vols_bybtype($type) ? TRUE : FALSE;
	}

	// $dtype is BACKUP or ARCHIVE
	// $ptype is pool type (PRIMARY,ACTIVE,COPY)
#zz
	public function getStorageModeVols($dtype,$ptype,$spo='') {
		$result = array();

		foreach ($this->_volumeusage() as $vo)
			if ($vo->COPY_TYPE == $dtype AND (! $spo OR $vo->STGPOOL_NAME == $spo) AND $vo->STGPOOL->POOLTYPE == $ptype)
				if (! isset($result[$vo->VOLUME_NAME]))
					$result[$vo->VOLUME_NAME] = $vo;

		return $result;
	}

	// $ptype is pool type (PRIMARY,ACTIVE,COPY)
#zz
	public function getStorageTypeVols($ptype,$spo='') {
		$result = array();

		foreach (Kohana::$config->load('config')->tsmdatatypes as $btype => $ctype)
			$result = array_merge($result,$this->getStorageModeVols($ctype,$ptype,$spo));

		return $result;
	}

	/**
	 * Return the data that this NODE has in a STORAGE POOL 
	 * @param $pool is STORAGE POOL NAME
	 * @param $metric is metric of the storpage pool, eg: NUM_FILES
	 */
	private function data_bypool($pool,$metric) {
		$k = sprintf('%s-%s-%s-%s',__METHOD__,$this->NODE_NAME,$pool,$metric);
		$c = Kohana::$config->load('config')->cache;

		if (is_null($result = Cache::instance($c)->get($k))) {
			$result = 0;

			foreach ($this->_occupancy() as $oo)
				if ($oo->STGPOOL_NAME == $pool)
					$result += $oo->{$metric};

			// @todo Cache time should be configurble
			Cache::instance($c)->set($k,$result,300);
		}

		return $result;
	}

	/**
	 * Return the FILES that this NODE has in a STORAGE POOL 
	 * @param $pool is STORAGE POOL NAME
	 */
	public function file_bypool($pool) {
		return $this->data_bypool($pool,'NUM_FILES');
	}

	/**
	 * Return the FILES that this NODE has in a STORAGE POOL TYPE
	 * @param $type is ACTIVEDATA/PRIMARY/COPY
	 */
	public function file_byptype($type) {
		$result = 0;

		foreach ($this->stgpools_byptype($type) as $spo)
			$result += $this->file_bypool($spo);

		return $result;
	}

	/**
	 * Return the LOGICAL_MB that this NODE has in a STORAGE POOL 
	 * @param $pool is STORAGE POOL NAME
	 */
	public function logmb_bypool($pool) {
		return $this->data_bypool($pool,'LOGICAL_MB');
	}

	/**
	 * Return the FILES that this NODE has in a STORAGE POOL TYPE
	 * @param $type is ACTIVEDATA/PRIMARY/COPY
	 */
	public function logmb_byptype($type) {
		$result = 0;

		foreach ($this->stgpools_byptype($type) as $spo)
			$result += $this->logmb_bypool($spo);

		return $result;
	}

	/**
	 * Return the STORAGE POOLS this NODE has data in
	 */
	public function stgpools() {
		$k = sprintf('%s-%s',__METHOD__,$this->NODE_NAME);
		$c = Kohana::$config->load('config')->cache;

		if (is_null($result = Cache::instance($c)->get($k))) {
			$x = $result = array();

			foreach ($this->_volumeusage() as $vuo)
				if (! in_array($vuo->STGPOOL_NAME,$x)) {
					array_push($result,$vuo->STGPOOL);
					array_push($x,$vuo->STGPOOL_NAME);
				}

			Sort::MASort($result,'STGPOOL_NAME');
			// @todo Cache time should be configurble
			Cache::instance($c)->set($k,$result,300);
		}

		return $result;
	}

	/**
	 * Return the STORAGE POOL TYPES used by this NODE
	 * ie: ACTIVE/PRIMARY/COPY
	 * @todo This should be sorted by PRIMARY/ACTIVE/COPY
	 */
	public function stgpooltypes() {
		$k = sprintf('%s-%s',__METHOD__,$this->NODE_NAME);
		$c = Kohana::$config->load('config')->cache;

		if (is_null($result = Cache::instance($c)->get($k))) {
			$result = array();

			foreach ($this->stgpools() as $spo)
				if (! in_array($spo->POOLTYPE,$result))
					array_push($result,$spo->POOLTYPE);

			// @todo Cache time should be configurble
			Cache::instance($c)->set($k,$result,300);
		}

		return $result;
	}

	/**
	 * Return the STORAGE POOLS that this NODE uses by BACKUP TYPE
	 * @param $type is BACKUP/ARCHIVE/SPACE MANAGED
	 */
	public function stgpools_bybtype($type) {
		$k = sprintf('%s-%s-%s',__METHOD__,$this->NODE_NAME,$type);
		$c = Kohana::$config->load('config')->cache;

		if (is_null($result = Cache::instance($c)->get($k))) {
			$x = $result = array();

			foreach ($this->_volumeusage() as $vuo)
				if ($vuo->COPY_TYPE == $type AND ! in_array($vuo->STGPOOL_NAME,$x)) {
					array_push($result,$vuo->STGPOOL);
					array_push($x,$vuo->STGPOOL_NAME);
				}

			Sort::MASort($result,'STGPOOL_NAME');
			// @todo Cache time should be configurble
			Cache::instance($c)->set($k,$result,300);
		}

		return $result;
	}

	/**
	 * Return the STORAGE POOLS that this NODE uses by BACKUP TYPE
	 * @param $type is ACTIVEDATA/PRIMARY/COPY
	 */
	public function stgpools_byptype($type) {
		$k = sprintf('%s-%s-%s',__METHOD__,$this->NODE_NAME,$type);
		$c = Kohana::$config->load('config')->cache;

		if (is_null($result = Cache::instance($c)->get($k))) {
			$result = array();

			foreach ($this->stgpools() as $spo)
				if ($spo->POOLTYPE == $type)
					array_push($result,$spo);

			// @todo Cache time should be configurble
			Cache::instance($c)->set($k,$result,300);
		}

		return $result;
	}

	/**
	 * Return the VOLUMES that this NODE uses by BACKUP TYPE
	 * @param $type is BACKUP/ARCHIVE/SPACE MANAGED
	 */
	public function vols_bybtype($type) {
		$k = sprintf('%s-%s-%s',__METHOD__,$this->NODE_NAME,$type);
		$c = Kohana::$config->load('config')->cache;

		if (is_null($result = Cache::instance($c)->get($k))) {
			$x = $result = array();

			foreach ($this->_volumeusage() as $vuo)
				if ($vuo->COPY_TYPE == $type AND ! in_array($vuo->VOLUME_NAME,$x)) {
					array_push($result,$vuo->VOLUME);
					array_push($x,$vuo->VOLUME_NAME);
				}

			Sort::MASort($result,'VOLUME_NAME');
			// @todo Cache time should be configurble
			Cache::instance($c)->set($k,$result,300);
		}

		return $result;
	}

	/**
	 * Return the VOLUMES that this NODE uses
	 * @param $pool is STORAGE POOL NAME
	 */
	public function vols_bypool($pool) {
		$k = sprintf('%s-%s-%s',__METHOD__,$this->NODE_NAME,$pool);
		$c = Kohana::$config->load('config')->cache;

		if (is_null($result = Cache::instance($c)->get($k))) {
			$x = $result = array();

			foreach ($this->_volumeusage() as $vuo) {
				if ($vuo->STGPOOL_NAME == $pool AND ! in_array($vuo->VOLUME_NAME,$x))
					array_push($result,$vuo);
					array_push($x,$vuo->VOLUME_NAME);
				}

			Sort::MASort($result,'VOLUME_NAME');
			// @todo Cache time should be configurble
			Cache::instance($c)->set($k,$result,300);
		}

		return $result;
	}

	/**
	 * Return the VOLUMES that this NODE has in a STORAGE POOL TYPE
	 * @param $type is ACTIVEDATA/PRIMARY/COPY
	 */
	public function vols_byptype($type) {
		$result = array();

		foreach ($this->stgpools_byptype($type) as $spo)
			$result = array_merge($result,$this->vols_bypool($spo));

		return $result;
	}

	/**
	 * Return the VOLUMES that this NODE uses by pool and BACKUP TYPE
	 * @param $pool is STORAGE POOL NAME
	 * @param $type is BACKUP/ARCHIVE/SPACE MANAGED
	 */
	public function vols_bypoolbybtype($pool,$type) {
		$x = $result = array();

		foreach ($this->vols_bypool($pool) as $vuo)
			if ($vuo->COPY_TYPE == $type AND ! in_array($vuo->VOLUME_NAME,$x)) {
				array_push($result,$vuo);
				array_push($x,$vuo->VOLUME_NAME);
			}

		return $result;
	}
}
?>
