#!/bin/sh -ef
# NAME=ODD read
# DESCRIPTION=This test checks for workability and correct optical discs reading of ODDs. It detects if disc is already loaded and tries to run test non-interactively (without any humans nearby). It reads needed number of blocks (trying readcd or dd), calculates their checksums and compares with specified one. So, we can determine either drives works fine or not. Also, simultaneously it acts as a monitoring, measuring disc reading speed.
# DESTROYS_HDD=false
# IS_INTERACTIVE=true
# POWEROFF_DURING_TEST=false
# VERSION=0.1
# TAGS=odd,monitoring
# DEPENDS=ODD
# VAR=TEST_IMAGE_HASH:string:6fa7786eef2e11d36e8bc1663679f161:Default image for comparison hash
# VAR=TEST_IMAGE_BLOCKS:int:332800:This images size in blocks (2048 bytes each)
# VAR=MESH_POINTS:int:1024:Points for meshes for monitoring drive's speed
# VAR=FORCE_NON_INTERACTIVE:boolean:false:Force non-interactive mode for already prepared system

. _inq-config-global; . $SHARE_DIR/functions-test

exit_handler()
{
	[ -f "$FIFOFILE" ] && rm -f $FIFOFILE
	[ -f "$FIFOFILE.md5" ] && rm -f $FIFOFILE.md5
	[ -f "$RESULT_FILE" ] && rm -f $RESULT_FILE
	[ -f "$TMPFILE" ] && rm -f $TMPFILE
}

FIFOFILE=`mktemp`
TMPFILE=`mktemp`
RESULT_FILE=`mktemp`

test_odd()
{
	local odd=$1

	# We are using FIFO file to read CD, calculate it's checksum
	# and retrieve speed measurements.
	rm $FIFOFILE
	mkfifo $FIFOFILE

	echo -n "Determining can we use readcd"
	readcd -v dev=$odd f=$TMPFILE sectors=0-1 >$DEBUG_TTY 2>&1 || true
	echo_success
	if [ ! -s "$TMPFILE" ]; then
		# So, we can not use readcd. No speed measurement then
		read_md5=`dd if=$odd bs=2048 count=$TEST_IMAGE_BLOCKS | md5sum -b | awk '{print $1}'` || true
	else
		md5sum -b "$FIFOFILE" > ${FIFOFILE}.md5 &
		readcd -v dev=$odd f=$FIFOFILE sectors=0-$TEST_IMAGE_BLOCKS meshpoints=$MESH_POINTS | while read line; do
			speed=`echo $line | awk '{print $2}'`
			timestamp=`date +%s`
			echo "$TESTED_QUANTITY	$timestamp	$speed" >> "$RESULT_FILE"
		done
		read_md5=`cat ${FIFOFILE}.md5 | awk '{print $1}'`
	fi
		
	echo "Read data MD5 checksum: $read_md5"
	[ "$read_md5" = $TEST_IMAGE_HASH ] \
		&& return 0 || return 1
}

interactive()
{
	local odd=$1
	local non_passed=1

	while ( [ "$non_passed" -eq 1 ] ); do
		eject $odd || true
		require_attention
		print_green_message "Drive ${odd}:"
		print_green_message "Either press y and insert media for testing, or n if you want to finish test: "
		read choice
		dismiss_attention

		if [ "$choice" = "n" ]; then
			test_failed "User cancelled test for $odd"
			break
		fi

		if test_odd $odd; then
			print_green_message "Drive test passed"
			TESTED_QUANTITY=$(( $TESTED_QUANTITY + 1 ))
			test_progress $TESTED_QUANTITY $ODD_QUANTITY
			non_passed=0

			eject $odd || true
			send_speed_results
		else
			print_red_message "Drive test failed"
		fi
	done
}

send_speed_results()
{
	[ -s "$RESULT_FILE" ] || return 0
	MONITORING_NAME=odd_read
	MONITORING_ID=6

	monitoring_submit_multiple "$RESULT_FILE"
}

need_kernel_module ide-cd

ODD_QUANTITY=`get_odds_list | wc -l`
test_succeed_if_no odds

TESTED_QUANTITY=0

for odd in `get_odds_list`; do
	print_green_message "Testing drive ${odd}..."

	if [ "$FORCE_NON_INTERACTIVE" == "true" ]; then
		# Forced non-interactive mode, no user actions allowed here
		if test_odd $odd; then
			TESTED_QUANTITY=$(( $TESTED_QUANTITY + 1 ))
			test_progress $TESTED_QUANTITY $ODD_QUANTITY
			send_speed_results
			eject $odd || true
		else
			test_failed "Bad ODD $odd"
		fi
	else
		# Default mode, try to test drive if media present
		if [ `check_readable_odd $odd` == "true" ];then
			print_green_message \
				"Found inserted media. Trying to test..."
			if test_odd $odd; then
				print_green_message "Drive test passed"
				TESTED_QUANTITY=$(( $TESTED_QUANTITY + 1 ))
				test_progress $TESTED_QUANTITY $ODD_QUANTITY
				send_speed_results
				eject $odd || true
			else
				print_red_message \
				"Drive test failed, going to interactive mode"
				interactive $odd
			fi
		else
			interactive $odd
		fi
	fi
done

test_succeeded
