#!/usr/bin/env bash
set -eux
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
bench_all=false
bench_buildroot_build=false
bench_buildroot_baseline_build=false
bench_gem5_build=false
bench_linux_boot=false
default_arch=x86_64
update_repo=false
while getopts Aa:Bbglu OPT; do
  case "$OPT" in
    A)
      bench_all=true
      ;;
    a)
      default_arch="$OPTARG"
      ;;
    b)
      bench_buildroot_build=true
      ;;
    B)
      bench_buildroot_baseline_build=true
      ;;
    g)
      bench_gem5_build=true
      ;;
    l)
      bench_linux_boot=true
      ;;
    u)
      update_repo=true
      ;;
    ?)
      exit 2
      ;;
  esac
done
shift "$(($OPTIND - 1))"
comment="${1:-}"
if \
  ! "$bench_buildroot_build" && \
  ! "$bench_buildroot_baseline_build" && \
  ! "$bench_gem5_build" && \
  ! "$bench_linux_boot" \
; then
  bench_all=true
fi
if "$bench_all"; then
  bench_buildroot_build=true
  bench_buildroot_baseline_build=true
  bench_gem5_build=true
  bench_linux_boot=true
fi
getvar="${root_dir}/getvar"

# Create output directory.
benchmark_repo="${root_dir}/../linux-kernel-module-cheat-regression"
mkdir -p "$benchmark_repo"
last_dir="$(ls "$benchmark_repo" | grep -E '^[0-9]' | tail -n 1)"
if [ -n "$last_dir" ]; then
  seq_id="$(("$(echo "$last_dir" | sed -E -e 's/_.*//' -e 's/^0*//')" + 1))"
else
  seq_id=0
fi
seq_id="$(printf '%0.4d' "$seq_id")"
dir_basename="${seq_id}_$("$getvar" sha)"
new_dir="${benchmark_repo}/${dir_basename}"
mkdir "$new_dir"

do_bench_buildroot_build() (
  arch="$default_arch"
  build_id=bench
  if [ "${1:-}" = baseline ]; then
    baseline=--baseline
    baseline_suffix=-baseline
  else
    baseline=
    baseline_suffix=
  fi
  common_build_dir="$("$getvar" --arch "$arch" --buildroot-build-id "$build_id" build_dir)"
  common_images_dir="$("$getvar" --arch "$arch" --buildroot-build-id "$build_id" buildroot_images_dir)"
  "${root_dir}/build-buildroot" --arch "$arch" $baseline --buildroot-build-id "$build_id" --clean
  "${root_dir}/build-buildroot" --arch "$arch" $baseline --buildroot-build-id "$build_id" --no-all -- source
  "${root_dir}/build-buildroot" --arch "$arch" $baseline --buildroot-build-id "$build_id"
  cp "${common_build_dir}/build-time.log" "${new_dir}/buildroot-build-time-${baseline_suffix}${arch}.log"
  wc -c "${common_images_dir}/"* > "${new_dir}/buildroot-image-size-${baseline_suffix}${arch}.log"
  "${root_dir}/build-buildroot" --arch "$arch" $baseline --buildroot-build-id "$build_id" --clean
)

if "$bench_buildroot_build"; then
  do_bench_buildroot_build
fi

if "$bench_buildroot_baseline_build"; then
  do_bench_buildroot_build baseline
fi

if "$bench_gem5_build"; then
  common_arch="$default_arch"
  gem5_build_id=bench
  common_gem5_build_dir="$("$getvar" --arch "$common_arch" --gem5-build-id "$gem5_build_id" gem5_build_dir)"
  common_gem5_source_dir="$("$getvar" --arch "$common_arch" --gem5-build-id "$gem5_build_id" gem5_source_dir)"
  results_file="${common_gem5_build_dir}/lkmc-bench-build.txt"
  git -C "${common_gem5_source_dir}" clean -xdf
  rm -f "$results_file"
  "${root_dir}/build-gem5" --arch "$common_arch" --clean --gem5-build-id "$gem5_build_id"
  # TODO understand better: --foreground required otherwise we cannot
  # kill the build with Ctrl+C if something goes wrong, can be minimized to:
  # bash -c "eval 'timeout 5 sleep 3'"
  "${root_dir}/bench-cmd" "timeout --foreground 900 ./build-gem5 --arch '$common_arch' --gem5-build-id '$gem5_build_id'" "$results_file"
  cp "$results_file" "${new_dir}/gem5-bench-build-${common_arch}.txt"
  git -C "${common_gem5_source_dir}" clean -xdf
  "${root_dir}/build-gem5" --arch "$common_arch" --clean --gem5-build-id "$gem5_build_id"
fi

if "$bench_linux_boot"; then
  cd "${root_dir}"
  "${root_dir}/build" --all-archs all
  "${root_dir}/test-boot" --size 3
  cp "$(${root_dir}/getvar test_boot_benchmark_file)" "$new_dir"
fi

if "$update_repo"; then
  if [ -n "$comment" ]; then
    echo "$comment" > "${new_dir}/README.adoc"
  fi
  echo
  cd "$benchmark_repo"
  git add .
  git commit -m "$dir_basename"
  git push
fi
