#!/bin/bash

set -eu

D=$(cd "$(dirname "$0")" && pwd)
FLUSTER_PY="$D"/fluster/fluster.py
VECTORS_OF_INTEREST=(
	# H.264
	'AUD_MW_E'
	'BA2_Sony_F'
	'BA3_SVA_C'
	'CABA3_Sony_C'
	'CAMA1_TOSHIBA_B'
	'cavlc_mot_fld0_full_B'
	'FREH10-1'
	'Hi422FREXT19_SONY_A'
	# H.265
	'AMP_A_Samsung_7'
	'INITQP_B_Main10_Sony_1'
	'WPP_F_ericsson_MAIN10_2'
	# H.266
	'10b400_A_Bytedance_2'
	'WRAP_D_InterDigital_4'
	# VP8
	'vp80-00-comprehensive-001'
	'vp80-00-comprehensive-012'
	'vp80-03-segmentation-1437'
	'vp80-01-intra-1400'
	# VP9
	'vp90-2-00-quantizer-00.webm'
	'vp90-2-00-quantizer-15.webm'
	'vp90-2-02-size-64x34.webm'
	'vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm'
	'vp90-2-21-resize_inter_1920x1080_7_1-2.webm'
	'vp91-2-04-yuv422.webm'
	'vp91-2-04-yuv444.webm'
	# AV1
	'00000675.ivf'
	'nonuniformtiling.ivf'
	'av1-1-b8-00-quantizer-61'
	'test-25fps-192x288-tile-rows-3-tile-cols-3.ivf'
	'av1-1-b8-23-filmgrain-50.ivf'
	'av1-1-b10-23-filmgrain-50.ivf'
	'av1-1-b8-03-sizeup'
)

for vector in "${VECTORS_OF_INTEREST[@]}"; do
    printf "%s\n" "$vector"
done > /tmp/fluster_test_suites_include


if [ ! -r "$FLUSTER_PY" ]; then
	git clone git@github.com:quine00/fluster.git
	cd fluster
	# My branch of fluster has hacked this to only download
	# VECTORS_OF_INTEREST.
	./fluster.py download
	# NOTE: GCC 15 failures at time of writing...
	# make all_reference_decoders
fi

gst_decoders_always_test=(
#	GStreamer-AV1-V4L2SL-Gst1.0
#	GStreamer-AV1-VA-Gst1.0
#	GStreamer-AV1-Vulkan-Gst1.0
#   TODO: package gstreamer-plugins-rs
#	GStreamer-AV1-dav1d-Gst1.0
#   TODO: OK to enable, takes a while though. Decoder conformance vs acceptable threshold...
#	GStreamer-AV1-libaom-Gst1.0
	GStreamer-H.264-Libav-Gst1.0
	FFmpeg-H.264

#   I don't think V4L2 decoders are that relevant for typical desktops...
#	GStreamer-H.264-V4L2-Gst1.0
#	GStreamer-H.264-V4L2SL-Gst1.0
	GStreamer-H.264-VA-Gst1.0
	GStreamer-H.264-VAAPI-Gst1.0
	FFmpeg-H.264-VAAPI
#	GStreamer-H.264-Vulkan-Gst1.0
	GStreamer-H.265-Libav-Gst1.0
	GStreamer-H.265-VA-Gst1.0
	GStreamer-H.265-VAAPI-Gst1.0
	FFmpeg-H.265
	FFmpeg-H.265-VAAPI
#	GStreamer-H.265-V4L2-Gst1.0
#	GStreamer-H.265-V4L2SL-Gst1.0
#	GStreamer-H.265-Vulkan-Gst1.0
	GStreamer-H.266-Libav-Gst1.0
	GStreamer-H.266-VA-Gst1.0
	GStreamer-H.266-VVdeC-Gst1.0
	FFmpeg-H.266
	FFmpeg-H.266-VAAPI
#	GStreamer-MPEG2_VIDEO-Libav-Gst1.0
#	GStreamer-MPEG2_VIDEO-SW-Gst1.0
#	GStreamer-MPEG4_VIDEO-Libav-Gst1.0
	GStreamer-VP8-Libav-Gst1.0
	GStreamer-VP8-VA-Gst1.0
	GStreamer-VP8-VAAPI-Gst1.0
	GStreamer-VP8-libvpx-Gst1.0
	FFmpeg-VP8
	FFmpeg-VP8-VAAPI
	GStreamer-VP9-VA-Gst1.0
	GStreamer-VP9-libvpx-Gst1.0
	FFmpeg-VP9
	FFmpeg-VP9-VAAPI

#	GStreamer-VP8-V4L2-Gst1.0
#	GStreamer-VP8-V4L2SL-Gst1.0
#	GStreamer-VP9-Libav-Gst1.0
#	GStreamer-VP9-V4L2-Gst1.0
#	GStreamer-VP9-V4L2SL-Gst1.0
#	GStreamer-VP9-Vulkan-Gst1.0
)

# shellcheck disable=SC2034
gst_decoders_test_on_amd_intel=(
#	GStreamer-VP9-VAAPI-Gst1.0
#	GStreamer-AV1-VAAPI-Gst1.0
)

# shellcheck disable=SC2034
gst_decoders_test_on_intel=(
#	GStreamer-H.264-MSDK-Gst1.0
)

# shellcheck disable=SC2034
gst_decoders_test_on_nvidia=(
#	GStreamer-H.264-NVDEC-Gst1.0
#	GStreamer-H.264-NVDECSL-Gst1.0
#	GStreamer-VP8-NVDEC-Gst1.0
#	GStreamer-VP8-NVDECSL-Gst1.0
#	GStreamer-VP9-NVDEC-Gst1.0
#	GStreamer-VP9-NVDECSL-Gst1.0
)

# Do we care?
# GStreamer-H.265-D3D11-Gst1.0
# GStreamer-H.265-D3D12-Gst1.0
# GStreamer-H.264-D3D11-Gst1.0
# GStreamer-H.264-D3D12-Gst1.0
# GStreamer-VP8-D3D11-Gst1.0
# GStreamer-AV1-D3D11-Gst1.0
# GStreamer-AV1-D3D12-Gst1.0
# GStreamer-VP9-D3D11-Gst1.0
# GStreamer-VP9-D3D12-Gst1.0

ensure_package_installed() {
  local pkgname="$1"
  if ! dpkg-query -W --showformat='${Status}' "$pkgname" 2>/dev/null | grep -q "install ok installed"; then
    echo "Error: The required package '$pkgname' is not installed. Please install it with:" >&2
    echo "  sudo apt-get install -y '$pkgname'" >&2
    exit 1
  fi
}
ensure_package_installed ffmpeg
ensure_package_installed gstreamer1.0-plugins-base
ensure_package_installed gstreamer1.0-plugins-good
ensure_package_installed gstreamer1.0-plugins-bad
ensure_package_installed gstreamer1.0-plugins-ugly
ensure_package_installed gstreamer1.0-libav
ensure_package_installed gstreamer1.0-vaapi

# shellcheck disable=SC2048
# shellcheck disable=SC2086
dispatch()
{
	echo $*
	eval $*
}

release=$(lsb_release -cs)
results=ubuntu_fluster_results.csv
vectors_of_interest=$(IFS=' '; echo "${VECTORS_OF_INTEREST[*]}")
all_errs=0
all_ok=0
echo "release,decoder,num_errs,num_ok,num_timeouts,num_not_run" > "$results"
for d in "${gst_decoders_always_test[@]}"; do
	summary=fluster_$d.out
	args=(--no-emoji
		  run
		  -d \'"$d"\'
		  -tv "$vectors_of_interest"
		  --summary-output "$summary"
		  -j 1
		  -f md)
	echo "running tests for $d..."
	dispatch python3 "$FLUSTER_PY" "${args[@]}" >fluster_"$d".log 2>&1 || true
	if [ -r "$summary" ]; then
		num_errs=$(grep -E '\|KO|\|ER' "$summary" | wc -l)
		num_not_run=$(grep -E '\|\|$' "$summary" | wc -l)
		num_ok=$(grep -E '\|OK\|$' "$summary" | wc -l)
		num_timeout=$(grep -cE '\|TO\|$' "$summary" | wc -l)
		echo "$release,$d,$num_errs,$num_ok,$num_timeout,$num_not_run" >> "$results"
		case "$d" in
			*GStreamer*)
				((all_errs+=num_errs)) || true
				((all_ok+=num_ok)) || true
				;;
		esac
	else
		echo "$release,$d,ERR,ERR,ERR,ERR" >> "$results"
	fi
done
tar czf "$D"/fluster_results.tar.gz ./*.out ./*.log ./*.csv && rm -f ./*.out ./*.log ./*.csv
[[ $all_ok -gt 40 && $all_errs -lt 15 ]] && exit 0 || exit 1
