#!/bin/bash
# - Test rewise --verify on installers.
# - Test rewise --extract on installers and check sha256 sums of extracted
#   files.
# - Test lying/corrupt WiseScript.bin


SELF_PATH="$(dirname $(realpath "$0"))"
CACHE_PATH="${SELF_PATH}/cache"
DL_PATH="${CACHE_PATH}/dl"
EXTRACT_PATH="${CACHE_PATH}/extract"
TMP_PATH="${CACHE_PATH}/tmp"


FILES=( \
	"hl1110.exe::http://archive.org/download/half-life-patches/English/Update 1.1.1.0 English/hl1110.exe" \
	"steaminstall_halflife.exe::http://archive.org/download/steaminstall_halflife/steaminstall_halflife.exe" \
	"hluplink.exe::http://archive.org/download/Half-lifeUplink/hluplink.exe" \
	"opfordemofull.exe::https://archive.org/download/opfor-demo/opfordemofull.exe" \
	"hl_sdk_v23.exe::https://downloads.ammahls.com/HLSDK/hl_sdk_v23.exe" \
	"csv15full.exe::https://archive.org/download/counter-strike-betas-windows/csv15full.exe" \
	"wolf_spdemo.exe::http://www.wolfenstein-files.de/rtcw/demos/wolf_spdemo.exe" \
	"Wolf_MPDemo.exe::http://www.wolfenstein-files.de/rtcw/demos/Wolf_MPDemo.exe" \
	"WolfET.exe::http://www.wolfenstein-files.de/et/demos/WolfET.exe" \
	"Wolf_Update_131_full.exe::https://archive.org/download/Wolf_Update_131_full_exe/Wolf_Update_131_full.exe"
)

SHA256_SUMS=( \
	"35baa2058bf41f872b418e1545d3a8bb92f13f7db211d734e522863b95651604" \
	"8ffa2117e8e49162b83adec298ac5c8e40c4dd5994950c0525f49b99374e5f71" \
	"9f236e9785980c127d46870a828ba4dac756308767ebd498b85bd7edff3305a8" \
	"55b48c810ee65e8b4da88d18ae248ab8e2ade2f9356ae44631bce74780217599" \
	"505a096000f8b53fe8d2a3c5dae33b226d69b556db13cc5f26a0b72fbd54be72" \
	"2963e480b02e5e29b2577d897ce99355d863d7db580b5d670e070baa2be3a0e5" \
	"bb92239488dc40459d68ecd8dffba7eda4824c41bd911e1483c85efe60eab035" \
	"fb5f6431535e8184826ebdf19fc51bfff34c4c6272da4ec8bd3c551fb989af54" \
	"7a5127c236f7d96534b59d085c654633fb081f28c89afc024eab606ca5eadaef" \
	"67033508330e78f8f9687c9b2fe697122dc50b447d9e1a3074627f6935315e3c"
)


dl_installer() {
	FILEPATH="$1"
	URL="$2"

	wget --quiet -O "${FILEPATH}" "${URL}"
	if [[ "$?" -ne "0" ]]; then
		echo "Failed"
		exit 1
	fi
}


verify_installer() {
	SHASUM="$1"
	FILEPATH="$2"

	sha256sum --quiet -c - <<< "${SHASUM} ${FILEPATH}"
	if [[ "$?" -ne "0" ]]; then
		echo "Mismatch"
		exit 1
	fi
}


clear_extract_dir() {
	rm -rf "${EXTRACT_PATH}" && mkdir "${EXTRACT_PATH}"
}


test_corrupted_patch() {
	PATCH_FILE="${SELF_PATH}/patches/$1"

	# Workaround to extract WiseScript.bin to the TMP path.
	../rewise -lp --tmp-path "${TMP_PATH}" "${DL_PATH}/hluplink.exe" 1>/dev/null

	# Backup the extracted WiseScript.bin
	mv "${TMP_PATH}/WiseScript.bin" "${TMP_PATH}/WiseScript.bin.bak"

	# Corrupt a filesize to 0xFFFFFFFF
	bspatch "${TMP_PATH}/WiseScript.bin.bak" "${TMP_PATH}/WiseScript.bin" "${PATCH_FILE}"

	# See how REWise reponds
	../rewise --no-extract --verify --silent --tmp-path "${TMP_PATH}" "${DL_PATH}/hluplink.exe"
	if [[ "$?" -eq "0" ]]; then
		# REWise did not fail, but it should have!
		echo "Failed"
		rm "${TMP_PATH}/WiseScript.bin"
		rm "${TMP_PATH}/WiseScript.bin.bak"
		exit 1
	fi

	rm "${TMP_PATH}/WiseScript.bin"
	rm "${TMP_PATH}/WiseScript.bin.bak"
	echo "OK"
}


# Create cache dirs
if [[ ! -d "${DL_PATH}" ]]; then
	mkdir -p "${DL_PATH}"
fi
if [[ ! -d "${EXTRACT_PATH}" ]]; then
	mkdir "${EXTRACT_PATH}"
fi
if [[ ! -d "${TMP_PATH}" ]]; then
	mkdir "${TMP_PATH}"
fi


# cd into SELF_PATH so rewise can be found by ../rewise
cd "${SELF_PATH}"


# Make sure rewise is present.
if [[ ! -f "../rewise" ]]; then
	echo "REWise (${SELF_PATH}/../rewise) not found."
	exit 1
fi


for i in ${!FILES[@]}; do
	FILE="${FILES[i]}"
	FILENAME="${FILE%%::*}"
	FILEURL="${FILE#*::}"
	FILEPATH="${DL_PATH}/${FILENAME}"

	echo "TEST ${FILENAME}"
	echo "-------------------------------------------------------------"

	# Make sure the installer file is present, else download it.
	if [[ ! -f "${FILEPATH}" ]]; then
		echo -n "DOWNLOAD file        : "
		dl_installer "${FILEPATH}" "${FILEURL}"
		echo "OK"
	fi

	# Verify installer file its sha256.
	echo -n "CHECK file integrity : "
	verify_installer "${SHA256_SUMS[i]}" "${FILEPATH}"
	echo "OK"

	# Test --verify
	# This assumes REWise will exit accordingly.
	echo -n "CHECK rewise verify  : "
	../rewise --verify --silent "${FILEPATH}"
	if [[ "$?" -ne "0" ]]; then
		echo "Failed"
		exit 2
	fi
	echo "OK"

	# Test --extract
	echo -n "CHECK rewise extract : "
	../rewise --extract "${EXTRACT_PATH}" --silent "${FILEPATH}"
	if [[ "$?" -ne "0" ]]; then
		echo "Failed"
		clear_extract_dir
		exit 2
	fi

	# Match sha256 sums of extracted files.
	(
		cd "${EXTRACT_PATH}"
		sha256sum --quiet -c "${SELF_PATH}/sums/${FILENAME}.extracted.sha256"
		if [[ "$?" -ne "0" ]]; then
			echo "Mismatch"
			clear_extract_dir
			exit 1
		fi
	)
	echo "OK"
	clear_extract_dir

	echo "-------------------------------------------------------------"
	echo ""
done


# Corrupt the WiseScript.bin from hluplink.exe and see how REWise responds,
# REWise should fail each time which will result in a OK.
#
# corrupt_filesize_1.patch
# Will patch a filesize in the WiseScript.bin to 0xFFFFFFFF
#
# corrupt_filesize_2.patch
# Will patch a filesize in the WiseScript.bin to 0x00000000
#
# corrupt_crc32.patch
# Will patch a CRC32 to an invalid one.
echo "Going to corrupt WiseScript.bin from hluplink.exe"
echo "-------------------------------------------------------------"
# Skip this test because REWise doesn't check if the inflated size is
# smaller then the advertised size anymore, it only checks if the
# inflated size is larger then the advertised/expected size.
#echo -n "Corrupt filesize 1   : "
#test_corrupted_patch "corrupt_filesize_1.patch"

echo -n "Corrupt filesize     : "
test_corrupted_patch "corrupt_filesize_2.patch"

echo -n "Corrupt CRC32        : "
test_corrupted_patch "corrupt_crc32.patch"
echo ""


function test_filtered_extract() {
	FILENAME="${1}"
	OPT_KEY="${2}"
	OPT_VAL="${3}"
	SHA_EXTRA="${4}"
	OPT_KEY2="${5}"
	OPT_VAL2="${6}"

	cd "${SELF_PATH}"

	echo -n "'${SHA_EXTRA}' for ${FILENAME}: "

	../rewise -x "${EXTRACT_PATH}" "${OPT_KEY}" "${OPT_VAL}" ${OPT_KEY2} ${OPT_VAL2} --silent "${DL_PATH}/${FILENAME}"

	if [[ "$?" -ne "0" ]]; then
		echo "Failed"
		clear_extract_dir
		exit 2
	fi

	cd "${EXTRACT_PATH}"
	sha256sum --quiet -c "${SELF_PATH}/sums/${FILENAME}.extracted.${SHA_EXTRA}.sha256"
	if [[ "$?" -ne "0" ]]; then
		echo "Mismatch"
		clear_extract_dir
		exit 1
	fi

	clear_extract_dir
	echo "Success!"
}


# Extract specific language test
echo "Test extracting by language"
echo "-------------------------------------------------------------"
test_filtered_extract "Wolf_Update_131_full.exe" "-g" 0 "en"
test_filtered_extract "Wolf_Update_131_full.exe" "-g" 2 "de"
echo ""


# Extract specific language test
echo "Test extracting by components and language"
echo "-------------------------------------------------------------"
test_filtered_extract "Wolf_Update_131_full.exe" "-g" 2 "de-A" "-c" "A"
test_filtered_extract "Wolf_Update_131_full.exe" "-g" 2 "de-B" "-c" "B"
echo ""


echo "All seems OK! :-D"
exit 0
