<?php
// $Header: /cvsroot/phptsmadmin/phpTSMadmin/htdocs/node.detail.php,v 1.11 2009/04/19 04:57:32 wurley Exp $

# This page should detail on Client storage usage.

# Required Libraries
require './common.php';

/**
 * This function returns an HTML table of the NODES FILE SYSTEMS for the $type
 */
function showFSDetails($node,$type) {
	if (! $node->getFSOccupancy($type))
		return null;

	$blockBody = '<table class="result_table">';
	switch ($type) {
		case 'Bkup' :
			$blockBody .= sprintf('<tr><td class="heading" colspan="%s">Backup Space Utilisation</td></tr>',
				3+count($node->getStoragePools()));
			break;

		case 'Arch' :
			$blockBody .= sprintf('<tr><td class="heading" colspan="%s">Archive Space Utilisation</td></tr>',
				3+count($node->getStoragePools()));
			break;

		default:
			return null;
	}

	$blockBody .= '<tr>';
	$blockBody .= '<td class="titlel">File System</td>';
	$blockBody .= '<td class="titlel">Last Backup</td>';
	$blockBody .= '<td class="titler">Last Size</td>';
	# List out the Storage Pools
	foreach ($node->getStoragePools() as $stgp)
		$blockBody .= sprintf('<td class="titler">%s</td>',$stgp);
	$blockBody .= '</tr>';

	$counter = 0;
	foreach ($node->getFSOccupancy($type) as $fs => $object) {
		$blockBody .= sprintf('<tr class="%s">',($counter++%2==0?'even':'odd'));
		$blockBody .= sprintf('<td><acronym title="%s">%s</acronym></td>',
			trim($object->type) ? $object->type : 'Unknown File System',$object->getName());

		$blockBody .= sprintf('<td><acronym title="%s - %s">%s&nbsp;</acronym></td>',
			isset($object->backup['start']) ? tsmdate($object->backup['start'],'nomsec') : 'NO START',
			isset($object->backup['end']) ? tsmdate($object->backup['end'],'nomsec') : 'NO END',
			isset($object->backup['end']) ? tsmdate($object->backup['end'],'notime') : 'NO DATE',
			$object->getName());

		$blockBody .= sprintf('<td align="right"><acronym title="%s MB (%s%%)">%s MB</acronym></td>',
			isset($object->capacity) ? number_format($object->capacity) : '?',
			isset($object->util) ? $object->util : '?',
			number_format($object->capacity*$object->util/100));

		foreach ($node->getStoragePools() as $stgp) {
			if (isset($object->occupancy[$type][$stgp]))
				$blockBody .= sprintf('<td align="right"><acronym title="%s files">%s</acronym>%s</td>',
					number_format($object->occupancy[$type][$stgp]['num'],0),
					number_format($object->occupancy[$type][$stgp]['physical'],2),
					count($object->getVolumeUsage($stgp)) ? sprintf(' <acronym title="# Volumes"><sub>(%s)</sub></acronym>',count($object->getVolumeUsage($stgp))) : '');
			else
				$blockBody .= '<td>&nbsp;</td>';
		}
		$blockBody .= '</tr>';
	}
	$blockBody .= '</table>';
	$blockBody .= "\n\n";

	return $blockBody;
}

/**
 * This function returns an HTML table of the VOLUMES used by a $node of $type
 */
function showVols($node,$type='Bkup') {
	if (! $node->getVolumes($type))
		return null;

	$blockBody = '<table class="result_table">';
	switch ($type) {
		case 'Bkup' :
			$blockBody .= sprintf('<tr><td class="heading" colspan="3">Backup Volume Utilisation</td></tr>');
			break;

		case 'Arch' :
			$blockBody .= sprintf('<tr><td class="heading" colspan="3">Archive Volume Utilisation</td></tr>');
			break;

		default:
			return null;
	}

	$blockBody .= '<tr>';
	$blockBody .= '<td class="titlel">File System</td>';
	$blockBody .= '<td class="titlel">Storage Pool</td>';
	$blockBody .= '<td class="titlel">Volume</td>';
	$blockBody .= '</tr>';

	$last['stg'] = '';
	$last['fs'] = '';
	$counter = 0;
	foreach ($node->getVolumes($type) as $fs => $object) {
		foreach ($object->volume[$type] as $stgp => $volumes) {
			foreach ($volumes as $vol => $volume) {
				$blockBody .= sprintf('<tr class="%s"><td>%s</td><td>%s</td><td>%s</td></tr>',
					($counter%2==0?'even':'odd'),
					$object->getName() == $last['fs'] ? '' : $object->getName(),
					$stgp == $last['stg'] ? '' : $stgp,
					sprintf('%s (%s/%s%s)',$vol,
						$volume->status['volume'],$volume->access,
						trim($volume->location) ? '-'.$volume->location : ''));

				$last['stg'] = $stgp;
				$last['fs'] = $object->getName();
			}
			$counter++;
		}
	}
	$blockBody .= '</table>';
	$blockBody .= "\n\n";

	return $blockBody;
}

/**
 * This function returns an HTML table of the VOLUMES by PRIMARY/COPY used by a $node of $type
 */
function showAllvols($node,$type='Bkup') {
	if (! $node->getVolumes($type))
		return null;

	$blockBody = '<table class="result_table">';
	switch ($type) {
		case 'Bkup' :
			$blockBody .= sprintf('<tr><td class="heading" colspan="2">Backup Volume Utilisation</td></tr>');
			break;

		case 'Arch' :
			$blockBody .= sprintf('<tr><td class="heading" colspan="2">Archive Volume Utilisation</td></tr>');
			break;

		default:
			return null;
	}

	$counter = 0;
	foreach ($node->getPrimaryVolumes($type) as $volumename => $volume) {
		$blockBody .= sprintf('<tr class="%s"><td>%s</td><td>%s</td></tr>',
			($counter%2==0?'even':'odd'),
				! $counter ? 'Primary' : '&nbsp;',
				sprintf('%s (%s/%s%s)',$volume->getName(),
					$volume->status['volume'],$volume->access,
					trim($volume->location) ? '-'.$volume->location : ''));
		$counter++;
	}

	$counter = 0;
	foreach ($node->getCopyVolumes($type) as $volumename => $volume) {
		$blockBody .= sprintf('<tr class="%s"><td>%s</td><td>%s</td></tr>',
			($counter%2==0?'even':'odd'),
				! $counter ? 'Copy' : '&nbsp;',
				sprintf('%s (%s/%s%s)',$volume->getName(),
					$volume->status['volume'],$volume->access,
					trim($volume->location) ? '-'.$volume->location : ''));
		$counter++;
	}

	$blockBody .= '</table>';
	$blockBody .= "\n\n";

	return $blockBody;
}

# Defaults
$nodes = objectCache('nodes');
$mgmtclass = objectCache('mgmtclasses');

# List of Clients.
printf(_('Select NODE on %s'),$app['server']->getValue('server','name'));

echo '<form action="cmd.php">';
printf('<input type="hidden" name="cmd" value="%s" />',get_request('cmd','REQUEST'));
printf('<input type="hidden" name="index" value="%s" />',$app['server']->getIndex());

echo '<select name="NODE">';
foreach ($nodes->getNodes() as $node) {
	printf('<option id="%s" %s>%s</option>',
		$node->getName(),
		isset($_REQUEST['NODE']) && $node->getName() == $_REQUEST['NODE'] ? 'selected' : '',
		$node->getName());
}
echo '</select>';
echo '<input align="left" type="submit" name="submit" value="Go" />';
echo '</form>';
echo "\n";

if (isset($_REQUEST['NODE'])) {
	echo '<br />';
	echo '<table class="result" width=100% border=0>';
	printf('<tr><td colspan=3><h3>NODE detail for <u>%s</u> on %s</h3></td></tr>',
		$_REQUEST['NODE'],$app['server']->getValue('server','name'));

	$node = $nodes->nodes[$_REQUEST['NODE']];
	if ($node->url)
		printf('<tr><td colspan=2>System Name</td><td><a href="%s"><b>%s</b></a></td></tr>',
			$node->url,$node->hostname);
	else
		printf('<tr><td colspan=2>System Name</td><td><b>%s</b></td></tr>',$node->hostname ? $node->hostname : '&nbsp;');

	printf('<tr><td colspan=2>Contact</td><td><b>%s</b></td></tr>',$node->contact ? $node->contact : '&nbsp;');

	printf('<tr><td colspan=2>OS</td><td><b>%s (%s)</b></td></tr>',
		$node->os,$node->level['os']);

	printf('<tr><td colspan=2>TSM Client Version</td><td><b>%s.%s.%s.%s</b></td></tr>',
		$node->level['tsm_ver'],$node->level['tsm_rel'],$node->level['tsm_lvl'],$node->level['tsm_slv']);

	echo '<tr><td colspan=3><h4>Access Information</h4></td></tr>';
	printf('<tr><td colspan=2>Registered</td><td><b>%s</b></td></tr>',
		tsmDate($node->time['registered'],'nosec'));
	printf('<tr><td colspan=2>Last Accessed</td><td><b>%s</b> (%2.0f days ago)</td></tr>',
		tsmDate($node->time['lastacc'],'nosec'),
		(time()-strtotime(tsmDate($node->time['lastacc'],'nosec')))/86400);
	printf('<tr><td colspan=2>Last Password Change</td><td><b>%s</b> (%2.0f days ago)</td></tr>',
		tsmDate($node->time['pwset'],'nosec'),
		(time()-strtotime(tsmDate($node->time['pwset'],'nosec')))/86400);
	printf('<tr><td colspan=2>Password Expiry</td><td><b>%s</b></td></tr>',
		tsmDate($node->passwd['expiry'],'nosec') ? tsmDate($node->passwd['expiry'],'nosec') : '&nbsp;');
	printf('<tr><td colspan=2>Invalid Password Count</td><td><b>%s</b> (%s)</td></tr>',
		$node->passwd['invalid'],
		$node->locked ? 'LOCKED' : 'NOT Locked');

	echo '<tr><td colspan=3><h4>Configuration Options</h4></td></tr>';
	printf('<tr><td colspan=2>Option Set</td><td><b>%s</b></td></tr>',$node->cloptset ? $node->cloptset : '&nbsp;');
	printf('<tr><td colspan=2>Compression </td><td><b>%s</b></td></tr>',
		$node->compression ? 'YES' : 'NO');
	printf('<tr><td colspan=2>TXN Group Max</td><td><b>%s</b></td></tr>',$node->txngroupmax ? $node->txngroupmax : '&nbsp;');
	printf('<tr><td colspan=2>Can Delete Archives</td><td><b>%s</b></td></tr>',
		$node->delete['arch'] ? 'YES' : 'NO');
	printf('<tr><td colspan=2>Can Delete Backups</td><td><b>%s</b></td></tr>',
		$node->delete['back'] ? 'YES' : 'NO');
	printf('<tr><td colspan=2>Keep Mount Points</td><td><b>%s</b> (%s)</td></tr>',
		$node->mp['keep'] ? 'YES' : 'NO',$node->mp['max']);

	echo '<tr><td colspan=3><h4>Storage Configuration</h4></td></tr>';
	printf('<tr><td colspan=2>Colloc Group Name</td><td><b>%s</b></td></tr>',$node->group ? $node->group : _('Not Set'));
	echo '<tr><td colspan=3>&nbsp;</td></tr>';
	printf('<tr><td colspan=2>Backup Domain</td><td><b>%s</b></td></tr>',$node->domain);

	# Show the MGMTClasses that apply to this node.
	printf('<tr><td>&nbsp;</td><td colspan=2><i>Available Backup Management Classes</i></td></tr>');
	foreach ($mgmtclass->getMgmtClasses($node->domain,'Bkup') as $object) {
		if (is_object($object))
			printf('<tr><td>&nbsp;</td><td><acronym title="File Exists: %s Version(s)/%s Day(s), File Deleted: %s Version(s)/%s Day(s), Frequency: %s Day(s)"><b>%s</b></acronym>%s</td><td>Storage Pool: <b>%s</b></td></tr>',
				$object->version['EXISTS'],$object->retain['EXTRA'],$object->version['DELETED'],$object->retain['ONLY'],$object->frequency,$object->getName(),
				$object->isDefaultMgmtClass() ? ' <sub>(Default)</sub>' : '',
				$object->getStoragePool() ? $object->getStoragePool()->getName() : sprintf('<sub>(%s)</sub>',_('Storage Pool Doesnt Exist')));
	}

	printf('<tr><td>&nbsp;</td><td colspan=2><i>Available Archive Management Classes</i></td></tr>');
	foreach ($mgmtclass->getMgmtClasses($node->domain,'Arch') as $object) {
		if (is_object($object))
			printf('<tr><td>&nbsp;</td><td><acronym title="Days: %s"><b>%s</b></acronym>%s</td><td>Storage Pool: <b>%s</b></td></tr>',
				$object->retain['DAYS'],$object->getName(),
				$object->isDefaultMgmtClass() ? ' <sub>(Default)</sub>' : '',
				$object->getStoragePool() ? $object->getStoragePool()->getName() : sprintf('<sub>(%s)</sub>',_('Storage Pool Doesnt Exist')));
	}

	echo '<tr><td colspan=3><h4>Storage Utilisation</h4></td></tr>';

	if ($node->getFileSystems()) {
		printf('<tr><td colspan=3>%s</td></tr>',showFSDetails($node,'Bkup'));
		echo '<tr><td colspan=3>&nbsp;</td></tr>';
		printf('<tr><td colspan=3>%s</td></tr>',showFSDetails($node,'Arch'));

	} else {
		echo '<tr><td colspan=3>TSM does not have any data for this host.</td></tr>';
	}

	if (count($node->getVolumeUsage())) {
		echo '<tr><td colspan=3><h4>Volume Utilisation</h4></td></tr>';
		printf('<tr><td colspan=3>%s</td></tr>',showAllVols($node,'Bkup'));
		echo '<tr><td colspan=3>&nbsp;</td></tr>';
		printf('<tr><td colspan=3>%s</td></tr>',showAllVols($node,'Arch'));

		echo '<tr><td colspan=3><h4>Volume Utilisation by File System</h4></td></tr>';
		printf('<tr><td colspan=3>%s</td></tr>',showVols($node,'Bkup'));
		echo '<tr><td colspan=3>&nbsp;</td></tr>';
		printf('<tr><td colspan=3>%s</td></tr>',showVols($node,'Arch'));
	}

	echo '</table>';
}
?>
