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

/**
 *
 * @package    PTA
 * @subpackage Domain
 * @category   Models
 * @author     Deon George
 * @copyright  (c) 2010 phpTSMadmin Development Team
 * @license    http://phptsmadmin.sf.net/license.html
 */
class Model_DOMAIN extends ORM_TSM {
	protected $_table_name = 'DOMAINS';
	protected $_primary_key = 'DOMAIN_NAME'; // We need a primary key to detect that the object is loaded.
	protected $_sorting = array(
		'DOMAIN_NAME'=>'ASC',
	);

	protected $_has_many = array(
		'MGMTCLASS'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME'),
		'NODE'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME'),
		'SCHEDULE_CLIENT'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME')
	);

	protected $_tsm = array(
		'db2'=>array(
			'_has_many'=>array(
				'MGMTCLASS'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME'),
				'NODE'=>array('foreign_key'=>'DOMAINNAME','far_key'=>'DOMAIN_NAME'),
				'SCHEDULE_CLIENT'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME')
			),
		),
	);

	/**
	 * Get all the NODES in this DOMAIN
	 */
	private function _nodes() {
		$k = sprintf('%s-%s',__METHOD__,$this->DOMAIN_NAME);
		$c = Kohana::$config->load('config')->cache;

		if (is_null($result = Cache::instance($c)->get($k))) {
			$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('NODE')->find_all() as $o)
				if ($o->DOMAIN_NAME == $this->DOMAIN_NAME)
					array_push($result,$o);

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

		return $result;
	}

	private function _node_int($method,$data) {
		$k = sprintf('%s-%s-%s-%s',__METHOD__,$this->DOMAIN_NAME,$method,$data);
		$c = Kohana::$config->load('config')->cache;

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

			foreach ($this->_nodes() as $no)
				$result += $no->{$method}($data);

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

		return $result;
	}

	private function _node_bypoolbybtype($pool,$method,$type) {
		$k = sprintf('%s-%s-%s-%s-%s',__METHOD__,$this->DOMAIN_NAME,$pool,$method,$type);
		$c = Kohana::$config->load('config')->cache;

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

			foreach ($this->_nodes() as $no)
				$result += $no->{$method}($pool,$type);

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

		return $result;
	}

	/**
	 * Return the BACKUP TYPES used by NODES in this DOMAIN
	 * ie: Bkup/Arch/SpMg
	 */
	public function btypes() {
		$k = sprintf('%s-%s',__METHOD__,$this->DOMAIN_NAME);
		$c = Kohana::$config->load('config')->cache;

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

			foreach ($this->_nodes() as $no)
				$result = array_merge($result,$no->btypes());

			$result = array_unique($result);

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

		return $result;
	}

	public function file_bybtype($type) {
		return $this->_node_int('file_bybtype',$type);
	}

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

	public function file_bypoolbybtype($pool,$type) {
		return $this->_node_bypoolbybtype($pool,'file_bypoolbybtype',$type);
	}

	public function file_byptype($type) {
		return $this->_node_int('file_byptype',$type);
	}

	public function logmb_bybtype($type) {
		return $this->_node_int('logmb_bybtype',$type);
	}

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

	public function logmb_bypoolbybtype($pool,$type) {
		return $this->_node_bypoolbybtype($pool,'logmb_bypoolbybtype',$type);
	}

	public function logmb_byptype($type) {
		return $this->_node_int('logmb_byptype',$type);
	}

	public function nodes() {
		return $this->_nodes();
	}

	public function nodes_bybtype($type) {
		$result = array();

		foreach ($this->_nodes() as $no)
			if ($no->file_bybtype($type))
				array_push($result,$no);
		return $result;
	}

	/**
	 * Return the NODES in this DOMAIN that have data in this STORAGE POOL
	 * @param $pool is STORAGE POOL NAME
	 */
	public function nodes_bypool(ORM $spo) {
		$result = array();

		foreach ($spo->nodes() as $no)
			if (in_array($no,$this->_nodes()))
				array_push($result,$no);

		return $result;
	}

	public function nodes_bypoolbybtype($pool,$type) {
		$result = array();

		foreach ($this->_nodes() as $no)
			if ($no->file_bypoolbybtype($pool,$type))
				array_push($result,$no);

		return $result;
	}

	public function nodes_byptype($type) {
		$result = array();

		foreach ($this->_nodes() as $no)
			if ($no->file_byptype($type) AND ! in_array($no,$result))
				array_push($result,$no);

		return $result;
	}

	/**
	 * Return the STORAGE POOLS used by NODES in this DOMAIN
	 */
	public function stgpools() {
		$k = sprintf('%s-%s',__METHOD__,$this->DOMAIN_NAME);
		$c = Kohana::$config->load('config')->cache;

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

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

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

		return $result;
	}

	/**
	 * Return the STORAGE POOLS that NODES in this DOMAIN uses by BACKUP TYPE
	 * @param $type is Bkup/Arch/SpMg
	 */
	public function stgpools_bybtype($type) {
		$k = sprintf('%s-%s-%s',__METHOD__,$this->DOMAIN_NAME,$type);
		$c = Kohana::$config->load('config')->cache;

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

			foreach ($this->_nodes() as $no)
				foreach ($no->stgpools_bybtype($type) as $spo)
					if (! in_array($spo->STGPOOL_NAME,$result))
						array_push($result,$spo);

			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 NODES in this DOMAIN uses by BACKUP TYPE
	 * @param $type is ACTIVEDATA/PRIMARY/COPY
	 */
	public function stgpools_byptype($type) {
		$k = sprintf('%s-%s-%s',__METHOD__,$this->DOMAIN_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 STORAGE POOL TYPES used by NODES in this DOMAIN
	 * ie: ACTIVE/PRIMARY/COPY
	 * @todo This should be sorted by PRIMARY/ACTIVE/COPY
	 */
	public function stgpooltypes() {
		$k = sprintf('%s-%s',__METHOD__,$this->DOMAIN_NAME);
		$c = Kohana::$config->load('config')->cache;

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

			foreach ($this->_nodes() as $no)
				$result = array_merge($result,$no->stgpooltypes());

			$result = array_unique($result);

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

		return $result;
	}

	public function vols_bybtype($type) {
		return $this->vols_byctype($this->datatypemap($type));
	}

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

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

			foreach ($this->_nodes() as $no)
				foreach ($no->vols_byctype($type) as $vo)
					if (! in_array($vo->VOLUME_NAME,$result))
						array_push($result,$vo);

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

		return $result;
	}

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

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

			foreach ($this->_nodes() as $no)
				foreach ($no->vols_bypool($pool) as $vo)
					if (! in_array($vo->VOLUME_NAME,$result))
						array_push($result,$vo);

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

		return $result;
	}

	public function vols_bypoolbybtype($pool,$type) {
		return $this->vols_bypoolbyctype($pool,$this->datatypemap($type));
	}

	/**
	 * 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_bypoolbyctype($pool,$type) {
		$x = $result = array();

		foreach ($this->_nodes() as $no)
			foreach ($no->vols_bypoolbyctype($pool,$type) as $vo)
				if (! in_array($vo->VOLUME_NAME,$result))
					array_push($result,$vo);

		return $result;
	}

	public function vols_byptype($type) {
		$x = $result = array();

		foreach ($this->_nodes() as $no)
			foreach ($no->vols_byptype($type) as $vuo)
				if (! in_array($vuo->VOLUME_NAME,$x)) {
					array_push($result,$vuo);
					array_push($x,$vuo->VOLUME_NAME);
				}

		return $result;
	}
}
?>
