#!/usr/bin/env python
# SPDX-License-Identifier: BSD-3-Clause

# Copyright (c) 2015 Google, Inc.
# Copyright (c) 2015 Linaro, Ltd.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from __future__ import print_function
import csv
import datetime
import sys
import time

dict = {'ping': '2', 'transfer': '3', 'sink': '4'}
verbose = 1

def abort():
	sys.exit(1)

def usage():
	print('Usage: looptest TEST SIZE ITERATIONS PATH\n\n'
	'  Run TEST for a number of ITERATIONS with operation data SIZE bytes\n'
	'  TEST may be \'ping\' \'transfer\' or \'sink\'\n'
	'  SIZE indicates the size of transfer <= greybus max payload bytes\n'
	'  ITERATIONS indicates the number of times to execute TEST at SIZE bytes\n'
	'             Note if ITERATIONS is set to zero then this utility will\n'
	'             initiate an infinite (non terminating) test and exit\n'
	'             without logging any metrics data\n'
	'  PATH indicates the sysfs path for the loopback greybus entries e.g.\n'
	'             /sys/bus/greybus/devices/endo0:1:1:1:1/\n'
	'Examples:\n'
	'  looptest transfer 128 10000\n'
	'  looptest ping 0 128\n'
	'  looptest sink 2030 32768\n'
	.format(sys.argv[0]), file=sys.stderr)

	abort()

def read_sysfs_int(path):
	try:
		f = open(path, "r");
		val = f.read();
		f.close()
		return int(val)
	except IOError as e:
		print("I/O error({0}): {1}".format(e.errno, e.strerror))
		print("Invalid path %s" % path)

def write_sysfs_val(path, val):
	try:
		f = open(path, "r+")
		f.write(val)
		f.close()
	except IOError as e:
		print("I/O error({0}): {1}".format(e.errno, e.strerror))
		print("Invalid path %s" % path)

def log_csv(test_name, size, iteration_max, sys_pfx):
	# file name will test_name_size_iteration_max.csv
	# every time the same test with the same parameters is run we will then
	# append to the same CSV with datestamp - representing each test dataset
	fname = test_name + '_' + size + '_' + str(iteration_max) + '.csv'

	try:
		# gather data set
		date = str(datetime.datetime.now())
		error = read_sysfs_int(sys_pfx + 'error')
		request_min = read_sysfs_int(sys_pfx + 'requests_per_second_min')
		request_max = read_sysfs_int(sys_pfx + 'requests_per_second_max')
		request_avg = read_sysfs_int(sys_pfx + 'requests_per_second_avg')
		latency_min = read_sysfs_int(sys_pfx + 'latency_min')
		latency_max = read_sysfs_int(sys_pfx + 'latency_max')
		latency_avg = read_sysfs_int(sys_pfx + 'latency_avg')
		throughput_min = read_sysfs_int(sys_pfx + 'throughput_min')
		throughput_max = read_sysfs_int(sys_pfx + 'throughput_max')
		throughput_avg = read_sysfs_int(sys_pfx + 'throughput_avg')

		# derive jitter
		request_jitter = request_max - request_min
		latency_jitter = latency_max - latency_min
		throughput_jitter = throughput_max - throughput_min

		# append data set to file
		with open(fname, 'a') as csvf:
			row = csv.writer(csvf, delimiter=",", quotechar="'",
					quoting=csv.QUOTE_MINIMAL)
			row.writerow([date, test_name, size, iteration_max, error,
					request_min, request_max, request_avg, request_jitter,
					latency_min, latency_max, latency_avg, latency_jitter,
					throughput_min, throughput_max, throughput_avg, throughput_jitter])
	except IOError as e:
		print("I/O error({0}): {1}".format(e.errno, e.strerror))

def loopback_run(test_name, size, iteration_max, sys_pfx):
	test_id = dict[test_name]
	try:
		# Terminate any currently running test
		write_sysfs_val(sys_pfx + 'type', '0')
		# Set parameter for no wait between messages
		write_sysfs_val(sys_pfx + 'ms_wait', '0')
		# Set operation size
		write_sysfs_val(sys_pfx + 'size', size)
		# Set iterations
		write_sysfs_val(sys_pfx + 'iteration_max', str(iteration_max))
		# Initiate by setting loopback operation type
		write_sysfs_val(sys_pfx + 'type', test_id)
		time.sleep(1)

		if iteration_max == 0:
			print ("Infinite test initiated CSV won't be logged\n")
			return

		previous = 0
		err = 0
		while True:
			# get current count bail out if it hasn't changed
			iteration_count = read_sysfs_int(sys_pfx + 'iteration_count')
			if previous == iteration_count:
				err = 1
				break
			elif iteration_count == iteration_max:
				break
			previous = iteration_count
			if verbose:
				print('%02d%% complete %d of %d ' %
					(100 * iteration_count / iteration_max,
					iteration_count, iteration_max))
			time.sleep(1)
		if err:
			print ('\nError executing test\n')
		else:
			log_csv(test_name, size, iteration_max, sys_pfx)
	except ValueError as ve:
		print("Error: %s " % format(e.strerror), file=sys.stderr)
		abort()

def main():
	if len(sys.argv) < 5:
		usage()

	if sys.argv[1] in dict.keys():
		loopback_run(sys.argv[1], sys.argv[2], int(sys.argv[3]), sys.argv[4])
	else:
		usage()
if __name__ == '__main__':
	main()
