#!/bin/bash

# usage: Refer to README.md / WIKI.md

# Process brief:
# run perf script, grep for qemu-kvm (this can be adjusted)
# then get the timestamp and metric fields, clean them and
# dump the data in a csv file

# read option from user, to skim native/thread types accordingly

user_interrupt(){
    echo -e "\n\nKeyboard Interrupt detected."
    echo -e "Cleaning Up and terminating..."
    if [ -f ${DUMP_PATH%/}/loop_diff.csv ]; then
        rm ${DUMP_PATH%/}/loop_diff.csv
        echo "removed ${DUMP_PATH%/}/loop_diff.csv"
    fi   
    if [ -f ${DUMP_PATH%/}/delta_output.log ]; then
        rm ${DUMP_PATH%/}/delta_output.log
        echo "${DUMP_PATH%/}/delta_output.log"
    fi   
    exit
}

trap user_interrupt SIGINT
trap user_interrupt SIGTSTP

declare -A skim_types=( [0]="skim_native" [1]="skim_threads")

while getopts "h?t:p:" opt; do
    case "$opt" in
	h|\?)
	    echo "Usage: $0 [-t skim for native/threads; specify 0/1 resp.] [-p path where data exists]..."
	    exit 0
	    ;;
	t)  skim_opt=$OPTARG
	    ;;
	p)  DUMP_PATH=$OPTARG
	    ;;
    esac
done

if [ ! -f /etc/delta_processor.conf ]; then
    echo "You need to specify configurations under /etc/delta_processor.conf"
    exit 1
fi

if [[ -z $DUMP_PATH ]]; then
    # defaults to /tmp
    DUMP_PATH='/tmp/pp_results/'
fi

if [[ -z $skim_opt ]]; then
    # defaults to Native
    skim_opt=0
fi

skim_pattern=$(grep "^${skim_types[$skim_opt]}" /etc/delta_processor.conf | awk -F' ' '{print $3}' | sed s#kvm_exit#kvm_exit.*IO_#g)

start_pp(){
    if [[ ! -z $DUMP_PATH ]]; then 
		# csv format processed from *.data / raw_perf previously
		if [ -f ${DUMP_PATH%/}/perf_data.csv ]; then
		    echo "Processing perf_data.csv ..."
		    delta_processor -i ${DUMP_PATH%/}/perf_data.csv \
				    -o $DUMP_PATH -m 0 -t $skim_opt \
				    -l ${DUMP_PATH%/}/delta_output.log 

		# plain text format processed from *.data previously
		elif [ -f ${DUMP_PATH%/}/raw_perf ]; then
		    echo "Processing raw_perf ..."
		    cat ${DUMP_PATH%/}/raw_perf | egrep 'qemu-kvm|qemu-system-x86' | awk -F' ' '{print $4,$5,$6,$7}' | \
			egrep $skim_pattern | awk -F' ' '{print $1,$2}' | \
			sed 's/sched://g' | sed 's/kvm://g' | sed 's/raw_syscalls://g' | sed 's/syscalls://g' | \
			sed 's/://g' | sed 's/ /,/g' > ${DUMP_PATH%/}/perf_data.csv
		    # add header to csv file
		    sed -i '1s/^/tstamp,entry\n/' ${DUMP_PATH%/}/perf_data.csv
		    delta_processor -i ${DUMP_PATH%/}/perf_data.csv \
				    -o $DUMP_PATH -m 0 -t $skim_opt \
				    -l ${DUMP_PATH%/}/delta_output.log

		# process *.data file directly (above if-else cases exist for data previously processed)
		elif [ -f ${DUMP_PATH%/}/perf.data ] || [[ $DUMP_PATH =~ .*[.]data  && -f $DUMP_PATH ]]; then
			# ensure that the <path>/custom_filename.data || <path>/perf.data exists		    
		    if [[ $DUMP_PATH =~ .*[.]data ]]; then
		    	echo "Processing $(basename $DUMP_PATH)"
			    perf script -i $DUMP_PATH| egrep 'qemu-kvm|qemu-system-x86' | awk -F' ' '{print $4,$5,$6,$7}' | \
				egrep $skim_pattern | awk -F' ' '{print $1,$2}' | \
				sed 's/sched://g' | sed 's/kvm://g' | sed 's/raw_syscalls://g' | sed 's/syscalls://g' | \
				sed 's/://g' | sed 's/ /,/g' > ${DUMP_PATH%$(basename $DUMP_PATH)}perf_data.csv
	
			    # add header to csv file
			    sed -i '1s/^/tstamp,entry\n/' ${DUMP_PATH%$(basename $DUMP_PATH)}/perf_data.csv
			    delta_processor -i ${DUMP_PATH%$(basename $DUMP_PATH)}perf_data.csv \
					    -o ${DUMP_PATH%$(basename $DUMP_PATH)} -m 0 -t $skim_opt \
					    -l ${DUMP_PATH%$(basename $DUMP_PATH)}delta_output.log
			else		
			    echo "Processing perf.data ..."
			    perf script | egrep 'qemu-kvm|qemu-system-x86' | awk -F' ' '{print $4,$5,$6,$7}' | \
				egrep $skim_pattern | awk -F' ' '{print $1,$2}' | \
				sed 's/sched://g' | sed 's/kvm://g' | sed 's/raw_syscalls://g' | sed 's/syscalls://g' | \
				sed 's/://g' | sed 's/ /,/g' > ${DUMP_PATH%/}/perf_data.csv
	
			    # add header to csv file
			    sed -i '1s/^/tstamp,entry\n/' ${DUMP_PATH%/}/perf_data.csv
			    delta_processor -i ${DUMP_PATH%/}/perf_data.csv \
					    -o $DUMP_PATH -m 0 -t $skim_opt \
					    -l ${DUMP_PATH%/}/delta_output.log
			fi


		else
		    echo "ERROR! one of: perf.data/perf_data.csv/raw_perf is required in path supplied.."
		    exit 1
		fi
		if [[ $DUMP_PATH =~ .*[.]data ]]; then
			echo "logs have been saved to ${DUMP_PATH%$(basename $DUMP_PATH)}delta_output.log"
		else
			echo "logs have been saved to ${DUMP_PATH%/}/delta_output.log"
		fi
    else
		echo "ERROR! You need to specify a dir path where perf.data resides"
		echo -e "Usage:\t$ ./perf_script_process.sh <dir where perf.data exists>"
		exit 1
    fi
}

start_pp
