#===============================================================#
#                                                               #
# $ID$                                                          #
#                                                               #
# perf_cpu_util.pl                                              #
#                                                               #
# Copyright (c) 2009 NetApp, Inc. All rights reserved.          #
# Specifications subject to change without notice.              #
#                                                               #
# This Sample code is supported from DataFabric Manager 3.7.1   #
# onwards.                                                      #
# However few of the functionalities of the sample code may     #
# work on older versions of DataFabric Manager.                 #
#===============================================================#

require 5.6.1;
use strict;
use warnings;

use lib '../../../../../../../lib/perl/NetApp';
use NaServer;
use NaElement;

# Command line arguments
my $args = scalar @ARGV;
my $dfm = shift;
my $user = shift;
my $pw  = shift;
my $storage_system = shift;

my @time_arr1;
my @time_arr2;
my @data_arr1;
my @data_arr2;

sub main() {
	# check for valid number of parameters
	if ($args != 4)	{
		die print_help();
	}

	# Initialize server context
	my $server_ctx = NaServer->new ($dfm, 1, 0);
	$server_ctx->set_transport_type("HTTP");
	$server_ctx->set_style("LOGIN");
	$server_ctx->set_admin_user($user, $pw);
	$server_ctx->set_server_type("DFM");
	$server_ctx->set_port(8088);

	# Start time and end time for week1 data collection
	#Start time = current time - (60sec * 60min * 24hrs * 14days)
	my $starttime1 = time - 1209600;
	#end time = current time - (60sec * 60min * 24hrs * 7days)
	my $endtime1 = time - 604800;

	# Start time and end time for week2 data collection
	#Start time = current time - (60sec * 60min * 24hrs * 7days)
	my $starttime2 = time - 604800;
	# end time = current time
	my $endtime2 = time;

	# Collect data for Week1
	my $perf_out1 = per_week_data($server_ctx, $starttime1, $endtime1);

	# Collect data for Week2
	my $perf_out2 = per_week_data($server_ctx, $starttime2, $endtime2);

	@time_arr1 = get_time_arr($perf_out1);
	@time_arr2 = get_time_arr($perf_out2);

	@data_arr1 = get_data_arr($perf_out1);
	@data_arr2 = get_data_arr($perf_out2);

	print_output();

	exit 0;
}

sub per_week_data() {
	my $server_ctx = $_[0];
	my $start_time = $_[1];
	my $end_time = $_[2];

	my $perf_in = NaElement->new("perf-get-counter-data");

	$perf_in->child_add_string("start-time", $start_time);
	$perf_in->child_add_string("end-time", $end_time);
	$perf_in->child_add_string("sample-rate", 3600);
	$perf_in->child_add_string("time-consolidation-method", "average");

	my $instance_info = NaElement->new("instance-counter-info");
	$instance_info->child_add_string("object-name-or-id", $storage_system);

	my $counter_info = NaElement->new("counter-info");
	my $perf_obj_ctr = NaElement->new("perf-object-counter");
	$perf_obj_ctr->child_add_string("object-type", "system");
	$perf_obj_ctr->child_add_string("counter-name", "avg_processor_busy");

	$counter_info->child_add($perf_obj_ctr);
	$instance_info->child_add($counter_info);
	$perf_in->child_add($instance_info);

	my $perf_out = $server_ctx->invoke_elem($perf_in);
	if($perf_out->results_status() eq "failed") {
		print($perf_out->results_reason() ."\n");
		exit(-2);
	}

	return $perf_out;
}

sub get_time_arr() {
	my $perf_out = $_[0];

	my $rec;
	my @time_arr;
	my @counter_arr;
	my $i=0;

	my $instance = $perf_out->child_get("perf-instances");
	my @instances = $instance->children_get("perf-instance-counter-data");

	foreach $rec (@instances){
		my $counters = $rec->child_get("counters");
		my @perf_cnt_data = $counters->children_get("perf-counter-data");
		my $rec1;

		foreach $rec1 (@perf_cnt_data) {
			my $counter_str = $rec1->child_get_string("counter-data");
			@counter_arr = split (/,/, $counter_str);
			my $time_val;

			foreach $time_val (@counter_arr) {
				my @time_val_arr = split(/:/, $time_val);
				$time_arr[$i++] = $time_val_arr[0];
			}
		}
	}

	return @time_arr;
}

sub get_data_arr() {
	my $perf_out = $_[0];

	my @counter_arr;
	my @data_arr;
	my $i=0;
	my $rec;

	my $instance = $perf_out->child_get("perf-instances");
	my @instances = $instance->children_get("perf-instance-counter-data");

	foreach $rec (@instances){
		my $counters = $rec->child_get("counters");
		my @perf_cnt_data = $counters->children_get("perf-counter-data");
		my $rec1;
		foreach $rec1 (@perf_cnt_data) {
			my $counter_str = $rec1->child_get_string("counter-data");
			@counter_arr = split (/,/, $counter_str);
			my $time_val;

			foreach $time_val (@counter_arr) {
				my @time_val_arr = split(/:/, $time_val);
				$data_arr[$i++] = $time_val_arr[1];
			}
		}
	}

	return @data_arr;
}

sub print_output() {

	print "Week1\t\tWeek2\t\n";
	print "Time\tCPU Busy\tTime\tCPU Busy\n";

	my $i;
	my $j;
	for ($i=0, $j=0; $i<scalar(@time_arr1) and $j<scalar(@time_arr2);) {
		if (($time_arr2[$j] - $time_arr1[$i]) > 608400) {
			print localtime($time_arr1[$i]) . "\t" . $data_arr1[$i++] . "\t";
			print "\t\t\n";
		} elsif (($time_arr2[$j] - $time_arr1[$i]) < 601200) {
			print "\t\t";
			print localtime($time_arr2[$j]) . "\t" . $data_arr2[$j++] . "\n";
		} else {
			print localtime($time_arr1[$i]) . "\t" . $data_arr1[$i++] . "\t";
			print localtime($time_arr2[$j]) . "\t" . $data_arr2[$j++] . "\n";
		}
	}
	while($i < scalar(@time_arr1)) {
        print localtime($time_arr1[$i]) . "\t" . $data_arr1[$i++] . "\t\t\t\n";
    }
    while($j < scalar(@time_arr2)){
        print "\t\t";
        print localtime($time_arr2[$j]) . "\t" . $data_arr2[$j++] . "\n";
    }
}

sub print_help() {
	print "\nCommand:\n";
	print "perf_cpu_util.pl <dfm> <user> <password> <storage-system>\n";
	print "<dfm>            -- DFM Server name\n";
	print "<user>           -- User name\n";
	print "<password>       -- Password\n";
	print "<storage-system> -- Storage system\n";
	print "-" x 80 . "\n";

	print "This sample code prints CPU utilization statistics of a storage \n";
	print "system. The sample code collects CPU utilization data for 2 weeks\n";
	print "and prints the data in a format, which enables comparision of CPU\n";
	print "utilization in day, hour format for both the weeks\n";
	print "Output data of this sample code can be used to generate chart.\n";
	print "To generate the graph, redirect output of this sample code to\n";
	print "an Excel sheet.\n";

	exit -1;
}

#Invoke routine
main();

#=========================== POD ============================#

=head1 NAME

  perf_cpu_util.pl - Prints CPU utilization statistics. This sample code
  compares CPU utilization statistics of 2 weeks.


=head1 SYNOPSIS

  perf_cpu_util.pl <dfm> <user> <password> <storage-system>

=head1 ARGUMENTS

  <dfm>
  DFM Server name.

  <user>
  User name.

  <password>
  Password.

  <storage-system>
  Storage system.

=head1 SEE ALSO

  NaElement.pm, NaServer.pm

=head1 COPYRIGHT

 Copyright (c) 2009 NetApp, Inc. All rights reserved.
 Specifications subject to change without notice.

=cut
