/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos72D src/bos/usr/ccs/lib/libperfstat/simplesspextstat.c 1.2          */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* Restricted Materials of IBM                                            */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2015,2016              */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
static char *sccsid = "@(#)85 1.2     src/bos/usr/ccs/lib/libperfstat/simplesspextstat.c, libperfstat, bos72D, d2016_10B7 3/6/16 20:59:25 ";
/* The sample program used to Display            *
 * the shared storage pool Tier/FG/PV information           */

#include <stdio.h>
#include <libperfstat.h>
#include <errno.h>

/* define default interval and count values */
#define INTERVAL_DEFAULT 1
#define COUNT_DEFAULT    1

/* Check value returned by malloc for NULL */

#define CHECK_FOR_MALLOC_NULL(X) {  if ((X) == NULL) {\
	perror ("malloc");\
	exit(2);\
}\
}

int count = COUNT_DEFAULT, interval = INTERVAL_DEFAULT;

/* store the data structures */
perfstat_ssp_t *sspstats = NULL;
int rc, returned_count, flag = 0;
char tiername[VIOS_STR_128];
char fgname[VIOS_STR_128];
char diskname[VIOS_STR_128];
char nodename[MAXHOSTNAMELEN];
perfstat_ssp_id_t sspid = {0};
int tflag = 0, dflag = 0,fflag = 0,nflag = 0;

/*
 * NAME: showusage
 *       to display the usage
 *
 */

void showusage()
{
	printf("Usage:simplesspstat -T | -F | -D | -N [-i interval] [-c count][-t <tiername> ][-f <failuregroupname>] [-d <diskname>] [-n <nodename>] \n");
	exit(1);
}

/*
 * NAME: do_initialization
 *       This function initializes the data structues.
 *       It also collects initial set of values.
 *
 * RETURNS:
 * On successful completion:
 *   - returns 0.
 * In case of error
 *   - exits with code 1.
 */

int do_initialization()
{
	int nofilter = 0;
	if(fflag || dflag || tflag || nflag)
		sspid.spec |= PERFFILT_NAME;
	else
		nofilter = 1;
		
	if(fflag)
	{
		sspid.spec |= PERFFILT_FG;
		strncpy(sspid.fg.name,fgname,VIOS_STR_128);
	}
	if(dflag)
	{
		sspid.spec |= PERFFILT_PHYSV;
		strncpy(sspid.pv.name,diskname,VIOS_STR_128);
	}
	if(tflag)
	{
		sspid.spec |= PERFFILT_TIER;
		strncpy(sspid.tier.name,tiername,VIOS_STR_128);
	}
	if(nflag)
	{
		sspid.spec |= PERFFILT_NODE;
		strncpy(sspid.node.name,nodename,VIOS_STR_128);

	}
	if(!nofilter)
	returned_count = perfstat_ssp_ext(&sspid, NULL, sizeof(perfstat_ssp_t),0,flag);
	else
	returned_count = perfstat_ssp_ext(NULL, NULL, sizeof(perfstat_ssp_t),0
,flag);
	if(returned_count <= 0){
		printf("perfstat_ssp_exit failed with error:%d",errno);
		exit(-1);
	}

	/* Allocate memory for the structure*/
	sspstats=( perfstat_ssp_t  *) malloc(sizeof(perfstat_ssp_t) * returned_count);

	CHECK_FOR_MALLOC_NULL(sspstats);

	return(0);
}

static void do_cleanup()
{
	free(sspstats);
}
/*
 *Name: display_metrics
 *      collect the metrics and display them
 *
 */
void display_metrics()
{

	int i,rc;
	int nofilter = 0;
	if(!fflag && !dflag && !tflag && !nflag)
		nofilter = 1;

	while (count)
	{
			/* Obtain SSP COnfig stats for tier/failure group or PV stats based on the flag*/
		if(!nofilter)
			rc=perfstat_ssp_ext(&sspid, sspstats, sizeof(perfstat_ssp_t),returned_count,flag);
		else
			rc=perfstat_ssp_ext(NULL, sspstats, sizeof(perfstat_ssp_t),returned_count,flag);
		
		if(rc<0)
		{ 
			perror("perfstat_ssp_t:");
			exit(-1);
		}

		sleep (interval);
		fprintf(stdout, "\nCluster Name  :  %s\n", sspstats->cluster_name);
		fprintf(stdout, "Storage Pool Name  :  %s\n", sspstats->spool_name);
		
			if(flag == SSPPV){
			
			if(rc!=0)	
				fprintf(stdout, "Disk name  \t Tier Name\t Failure Group:\n");
			else
				fprintf(stdout, "There are no disks in the storage pool\n");

			for(i=0; i<returned_count; i++){
				fprintf(stdout, "%8s\t%8s\t%13s\n  ",sspstats[i].u.disk.diskname,sspstats[i].u.disk.tiername,sspstats[i].u.disk.fgname);
			}   
		}   

		if(flag == SSPTIER)
		{
			if(rc!=0)	
				fprintf(stdout, "Tier name  \t Tier ID\n");
			else
				fprintf(stdout, "There are no tiers in the storage pool\n");

			for(i=0; i<returned_count; i++){
				fprintf(stdout, "%8s\t%6llu\n  ",sspstats[i].u.tier.tiername,sspstats[i].u.tier.tierid);
			}   



		}

		if(flag == SSPFG)
		{
			if(rc!=0)	
				fprintf(stdout, "FailureGroupName  FailureGroupID  TierName  Tier ID\n");
			else
				fprintf(stdout, "There are no failuregroups in the storage pool\n");

			for(i=0; i<returned_count; i++){
				fprintf(stdout, "%16s\t%15llu\t%8s\t%6llu\n  ",sspstats[i].u.fg.fgname,sspstats[i].u.fg.fgid,sspstats[i].u.fg.tiername,sspstats[i].u.fg.tierid);
			}   

		}
		if(flag ==  SSPNODE)
		{
		for ( i =0; i <returned_count ; i++)
		{
			fprintf(stdout,"Nodename:%s,mtms:%s,status:%d,poolstatus:%d,ip:%s,lparid:%d\n",sspstats[i].u.node.hostname,sspstats[i].u.node.mtms,sspstats[i].u.node.status,sspstats[i].u.node.poolstatus,sspstats[i].u.node.ip,sspstats[i].u.node.lparid);	
		}
		}

		fprintf(stdout,"\n\n");
		count--;
	} 
}

int main(int argc, char* argv[])
{

	int c,Tflag=0,Dflag=0,Fflag=0,Nflag = 0;
	/* Enable the cluster statistics using perfstat_config */
	rc = perfstat_config(PERFSTAT_ENABLE|PERFSTAT_CLUSTER_STATS, NULL);
	if (rc == -1)
	{
		perror("cluster statistics collection is not available");
		exit(-1);
	}

	while((c = getopt(argc, argv, "i:c:TFDNt:f:d:n:"))!= EOF){
		switch(c){
			case 'i':           
				interval = atoi(optarg);
				if( interval <= 0 )
					interval = INTERVAL_DEFAULT;
				break;
			case 'c':               
				count = atoi(optarg);
				if( count <= 0 )
					count = COUNT_DEFAULT;
				break;
			case 'T':
				flag = SSPTIER;
				Tflag = 1;
				break;
			case 'F':		
				flag = SSPFG;
				Fflag = 1;
				break;
			case 'D':	
				flag = SSPPV;
				Dflag = 1;
				break;
			case 'N':	
				flag = SSPNODE;
				Nflag = 1;
				break;
			case 't':
				tflag = 1;
				strncpy(tiername,optarg,VIOS_STR_128);
				break;
			case 'f':
				fflag = 1;
				strncpy(fgname,optarg,VIOS_STR_128);
				break;
			case 'd':
				dflag = 1;
				strncpy(diskname,optarg,VIOS_STR_128);
				break;
			case 'n':
				nflag = 1;
				strncpy(nodename,optarg,MAXHOSTNAMELEN);
				break;

			default:
				showusage(argv[0]);
		}
	}

	if(flag == 0){
		showusage(argv[0]);
	}

	if(Tflag )
	{
		if (Fflag || Dflag || fflag || dflag || Nflag || nflag){
			showusage(argv[0]);
		}
	}	

	if(Fflag)
	{
		if(Tflag || Dflag || dflag || Nflag || nflag){
			showusage(argv[0]);
		}
	}

	if(Dflag)
	{
		if(Tflag || Fflag || Nflag || nflag)
			showusage(argv[0]);
	}
	if(Nflag)
	{
		if(Tflag || Fflag || Dflag || fflag || dflag || tflag )
			showusage(argv[0]);
	}
	do_initialization();
	display_metrics();

	/* Now disable cluster statistics by calling perfstat_config */
	perfstat_config(PERFSTAT_DISABLE|PERFSTAT_CLUSTER_STATS, NULL);

	do_cleanup();
	/*realloc(sspstats);*/
	return 0;
}


