#!/bin/bash

ROOT_DIR="$(realpath $(dirname $0)/..)"

set -u
set -e
#set -x

source "$ROOT_DIR/lib/nmon-utils.sh"

_usage()
{
    echo -ne \
        "\nUsage:" \
        "\n    $(basename $0) -?|-h|--help" \
        "\n    $(basename $0) [options] <source-dir>" \
        "\n" \
        "\nOptions:" \
        "\n    -h, -?, --help         print this help message" \
        "\n    -w, --work-dir <path>  path to place output files/logs" \
        "\n\n"
}

_wrk_stats()
{
    local -r wrk_out="$1/wrk.out"

    # Througput (Gbps)
    cat "$wrk_out" \
        | grep "Transfer/sec" \
        | tr -s ' ' | cut -d' ' -f2 | tr -d 'B' \
        | numfmt --from=iec --round=down \
        | awk '{printf "%.3f\n", ($0*8)/(1024*1024*1024)}'

    # Rate (RPS)
    cat "$wrk_out" | grep "Requests/sec" | tr -s ' ' | cut -d' ' -f2
}

_nginx_stats()
{
    local -r source=$1
    local -r offset=$2

    for f in "$source"/*.nmon; do
        paste -d, <(cat "$f" | nmon_parse_cpu "$offset") <(cat "$f" | nmon_parse_mem 0) | tail -n +2 | head -n 1
        return # process only first file
    done
}

_process()
{
    local -r source=$1

    IFS=- read mode proto payload threads connections <<<"$(echo $(basename $source))"
    #echo -e "$(basename $source)\tmode=$mode\tproto=$proto\tpayload=$payload\tthreads=$threads\tconnections=$connections"

    # parse wrk stats
    local total_tp=0
    local total_rps=0
    for c in "$source"/client*; do
        read tp rps <<< $(_wrk_stats "$c" | tr '\n' ' ')
        total_tp=$(echo "scale=3; $total_tp + $tp" | bc | awk '{printf "%.3f\n", $0}')
        total_rps=$(echo "scale=3; $total_rps + $rps" | bc | awk '{printf "%.3f\n", $0}')
    done

    # parse nginx stats
    read cpu_avg cpu_num mmin mmax mem_diff mtotal smin smax swap_diff stotal \
        <<< $(_nginx_stats "$source/server" 0 | tr ',' ' ')

    # print resulting csv line
    echo "$mode,$proto,$payload,$threads,$connections,$total_tp,$total_rps,$cpu_avg,$cpu_num,$mem_diff,$swap_diff"
}

_main()
{
    # defaults
    local work_dir="$ROOT_DIR/run/bench-report"

    # parse options
    while true; do
        case "$1" in
            -h|-\?|--help) _usage; exit 0;;
            -w|--work-dir) work_dir="$2"; shift 2;;
            -?*) { echo "unknown option: $1"; _usage; exit 1; } >&2;;
            *) break;;
        esac
    done

    # parse args
    local -r source_dir=$1

    # print csv header
    mkdir -p "$work_dir"
    local -r csv_report="$work_dir/report.csv"
    echo "Mode(kernel/xlio),Proto(http/https),Payload,Workers,Connections,Throughput(Gbps),Rate(RPS),CPU(%),CPUs,Mem(MB),Swap(MB)" > "$csv_report"

    # process each step from bulk run
    for s in "$source_dir"/*-*-*-*-*; do
        [ -d "$s" ] || continue
        echo "processing $(basename $s)"
        _process "$s" >> "$csv_report"
    done

    echo "sorting $csv_report"
    (head -n1 "$csv_report" && tail -n+2 "$csv_report" | sort -t, -k5n,5n -k1,2 -k4n,4n -k3h,3h) > "$csv_report.tmp"
    mv -f "$csv_report.tmp" "$csv_report"

    echo "report file $csv_report"
}

_main "$@"
