#===============================================================#
#                                                               #
# ID                                                            #
#                                                               #
# perf_disk_iops_latency.py                                     #
#                                                               #
# Copyright (c) 2011 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.                 #
#===============================================================#

import sys
import time
sys.path.append("../../../../../../../lib/python/NetApp")
from NaServer import *
nsamples = 0

def main() :
    # check for valid number of parameters
    perf_out = invoke_perf_zapi()
    extract_perf_counter_data(perf_out)
    print_output()
    sys.exit (2)


def invoke_perf_zapi() :
    # Initialize server context
    server_ctx = NaServer (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)

    # Create API request
    perf_in = NaElement("perf-get-counter-data")
    perf_in.child_add_string("duration", 6000)
    perf_in.child_add_string("number-samples", 50)
    perf_in.child_add_string("time-consolidation-method", "average")

    instance_info = NaElement("instance-counter-info")
    instance_info.child_add_string("object-name-or-id", aggr_name)

    counter_info = NaElement("counter-info")
    perf_obj_ctr = NaElement("perf-object-counter")
    perf_obj_ctr.child_add_string("object-type", "disk")
    perf_obj_ctr.child_add_string("counter-name", "total_transfers")

    counter_info.child_add(perf_obj_ctr)
    instance_info.child_add(counter_info)
    perf_in.child_add(instance_info)

    perf_out = server_ctx.invoke_elem(perf_in)
    
    if(perf_out.results_status() == "failed") :
        print(perf_out.results_reason() + "\n")
        sys.exit(2)
    
    return perf_out


def extract_perf_counter_data(perf_out) :
    gen_time_arr = 1
    instance = perf_out.child_get("perf-instances")
    instances = instance.children_get()
    global nsamples,i,disk_i
    if(instances != None):
        for rec in instances :
            disk_name = rec.child_get_string("object-id")
        
            if (disk_name) :
                disk_arr.append(disk_name)
                disk_i = disk_i + 1
        
        counters = rec.child_get("counters")
        perf_cnt_data = counters.children_get()
        
        for rec1 in perf_cnt_data :
            counter_str = rec1.child_get_string("counter-data")
            counter_arr = counter_str.split (',')
            
            for time_val in counter_arr :
                time_val_arr = [float(s) for s in time_val.split(':')]
                
                if(gen_time_arr) :
                    time_arr.append(time.localtime(time_val_arr[0]))
                    nsamples = i + 1
            
                data_arr.append(time_val_arr[1])
                i = i + 1 
            gen_time_arr = 0
    
    
# Print output.
def print_output() :
    sys.stdout.write("\nTime\t\t\t\t")    
    # Print disk ID.
    l = 0
    while(l < disk_i):
        sys.stdout.write(disk_arr[l])
        sys.stdout.write("\t")
        l = l + 1
    
    print ("Min Val\tMax Val\n")
    j = 0
    k = 0
    iter = 0
    
    while(iter < nsamples):
        m = 0
        min_util = 9999999999999    #dum value
        max_util = 0
        min_index = 0
        max_index = 0
        k = iter
        sys.stdout.write(time.asctime(time_arr[iter]))
        sys.stdout.write("\t")
        
        while(k < i):
            sys.stdout.write(str(data_arr[k]))
            sys.stdout.write("\t")

            if (min_util > data_arr[k]) :
                min_util = data_arr[k]
                min_index = m
            
            if (max_util < data_arr[k]) :
                max_util = data_arr[k]
                max_index = m
            
            m = m + 1
            k = k + nsamples
        
        print("%.3f\t%.3f" %(min_util,max_util))
        iter = iter + 1
    
    sys.exit(2)


def print_help() :
    print ("\nCommand:\n")
    print ("perf_disk_iops_latency.py <dfm> <user> <password> <aggr-name>\n")
    print ("<dfm>        -- DFM Server name\n")
    print ("<user>       -- User name\n")
    print ("<password>   -- Password\n")
    print ("<aggr-name>    -- Name of the aggregate in format storage:aggrName\n")
    print ("-" * 80 + "\n")

    print ("This sample code prints disk IOPs for the disks on which the\n")
    print ("given aggregate is present. This sample code also does prints \n")
    print ("minimum disk IOPs value and maximum disk IOPs value for the \n")
    print ("specific time stamp. \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")
    sys.exit (1)

# Command line arguments
args = len(sys.argv) - 1

if(args < 4):
    print_help()

dfm = sys.argv[1]
user = sys.argv[2]
pw  = sys.argv[3]
aggr_name = sys.argv[4]
time_arr = []
data_arr = []
disk_arr = []
disk_i = 0
nsamples = 0
i = 0

#Invoke routine
main()

'''#=========================== POD ============================#

=head1 NAME

  perf_disk_iops_latency.py - This sample code prints disk IOPs for the disks
  on which the given aggregate is present. This sample code also does prints
  minimum disk IOPs value and maximum disk IOPs value for the specific
  time stamp.

=head1 SYNOPSIS

  perf_disk_iops_latency.py <dfm> <user> <password> <aggr-name>

=head1 ARGUMENTS

  <dfm>
  DFM Server name.

  <user>
  User name.

  <password>
  Password.

  <aggr-name>
  Name of the aggregate in format storage:aggrName.

=head1 SEE ALSO

  NaElement.py, NaServer.py

=head1 COPYRIGHT

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

=cut'''

