#!/bin/bash

# Functions borrowed or derived from
# Michael Bryant / Shadow53
# https://gitlab.com/Shadow53/android-zip-builder

repo_fdroid="https://f-droid.org/repo"
repo_guardian="https://guardianproject.info/fdroid/repo"
repo_microg="https://microg.org/fdroid/repo"
repo_nanolx="https://nanolx.org/fdroid/repo"
repo_bromite="https://fdroid.bromite.org/fdroid/repo"
repo_ogapps="https://gitlab.opengapps.org/opengapps"

useragent='Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0'

if [ "${BP_DEBUG}" = '1' ]; then
	wget_opts="-v --show-progress"
	curl_opts="-vSL"
else
	wget_opts="-q"
	curl_opts="-sSL"
fi

# check dependencies
for dep in gawk curl jq gzip grep; do
	if ! which ${dep} &>/dev/null; then
		echo "${dep} is not installed!"
		exit 1
	fi
done

debug_download () {
	case $1 in
		index)
			if [ "${BP_USE_WGET}" = '1' ]; then
				rm -rf "$2"
				debug_message normal "wget ${wget_opts} \"$3\" -O \"${2#$CWD/}\"" " "
				wget ${wget_opts} -U "${useragent}" "$3" -O "$2" || error "$4"
			else
				debug_message normal "curl ${curl_opts} \"${2#$CWD/}\" \"$3\"" " "
				curl ${curl_opts} -A "${useragent}" -o "$2" "$3" || error "$4"
			fi
		;;
		no_delete)
			if [ "${BP_USE_WGET}" = '1' ]; then
				rm -rf "$2"
				debug_message normal "wget ${wget_opts} \"$3\" -O \"${2#$CWD/}\""
				wget ${wget_opts} -U "${useragent}" "$3" -O "$2"
			else
				debug_message normal "curl ${curl_opts} -SL -o \"${2#$CWD/}\" \"$3\""
				curl ${curl_opts} -A "${useragent}" -o "$2" "$3"
			fi
		;;
		delete)
			if [ "${BP_USE_WGET}" = '1' ]; then
				rm -rf "$2"
				debug_message normal "wget ${wget_opts} \"$3\" -O \"${2#$CWD/}\""
				wget ${wget_opts} -U "${useragent}" "$3" -O "$2" || rm -f "$4"
			else
				debug_message normal "curl ${curl_opts} -SL -o \"${2#$CWD/}\" \"$3\""
				curl ${curl_opts} -A "${useragent}" -o "$2" "$3" || rm -f "$4"
			fi
		;;
	esac
}

index_update_required () {
	index_file=${1}

	test ! -f ${index_file} && return 0
	test $(${statx} ${index_file}) -le $(($(date +%s) - 3600)) && return 0
	test "$(file -b ${index_file})" == "empty" && return 0

	return 1
}

check_sha256sum () {
	local input="${1}"

	in_checksum=""
	local ex_checksum="${2}"

	case ${input} in
		*.gz )
			in_checksum=$(gzip -dc ${input} 2>/dev/null | ${sumsha256} | gawk '{print $1}')
		;;

		* )
			in_checksum=$(${sumsha256} ${input} 2>/dev/null | gawk '{print $1}')
		;;
	esac

	[[ ${in_checksum} == ${ex_checksum} ]] && return 0 || return 1
}

update_index () {
	local index_jar=${1}
	local index_json="$repofolder/$(basename ${index_jar} .jar).json"
	local index_repo=${2}

	if index_update_required ${index_json}; then
		debug_download index "${index_jar}" "${index_repo}/index-v1.jar" " failed to update repo index"

		unzip -q ${index_jar} index-v1.json -d "$repofolder/"
		mv "$repofolder/index-v1.json" "${index_json}"
		rm -f ${index_jar}
	fi
}

update_indices () {
	echo "+++ upating Repo Indices"
	echo " ++ F-Droid"
	[ ! -d "$repofolder" ] && rm -rf "$repofolder" && mkdir -p "$repofolder"
	update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_fdroid}).index-v1.jar" "${repo_fdroid}"

	echo " ++ Guardian Project"
	update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_guardian}).index-v1.jar" "${repo_guardian}"

	echo " ++ microG"
	update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_microg}).index-v1.jar" "${repo_microg}"

	echo " ++ Nanolx"
	update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_nanolx}).index-v1.jar" "${repo_nanolx}"

	echo " ++ Bromite"
	update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_bromite}).index-v1.jar" "${repo_bromite}"
}

grab_apk_from_repo () {
	case "${1}" in
		fdroid )
			local repo=${repo_fdroid}
			local repo_p="F-Droid"
		;;

		guardian )
			local repo=${repo_guardian}
			local repo_p="Guardian Project"
		;;

		microg )
			local repo=${repo_microg}
			local repo_p="microG"
		;;

		nanolx )
			local repo=${repo_nanolx}
			local repo_p="Nanolx"
		;;

		bromite )
			local repo=${repo_bromite}
			local repo_p="Bromite"
		;;
	esac

	local domain="$(awk -F/ '{print $3}' <<< ${repo})"
	index_file="$repofolder/${domain}.index-v1.json"

	local pkg_name="${2}"

	if [ -z "${5}" ]; then
		local apk_name="$(jq -r --arg pkg "${pkg_name}" '.packages[$pkg][0].apkName' ${index_file})"
		local sha_sum="$(jq -r --arg pkg "${pkg_name}" '.packages[$pkg][0].hash' ${index_file})"
	else
		local apk_name="$(jq -r --arg pkg "${pkg_name}" --arg arch "${5}" '[.packages[$pkg][] | select (.nativecode[]==$arch).apkName][0]' ${index_file})"
		local sha_sum="$(jq -r --arg pkg "${pkg_name}" --arg arch "${5}" '[.packages[$pkg][] | select (.nativecode[]==$arch).hash][0]' ${index_file})"
	fi

	case "${pkg_name}" in
		com.android.webview )
			local apk_dest="${appsfolder[12]}/${3}/${4}"
		;;

		net.osmand.plus | net.osmand.srtmPlugin.paid )
			local apk_dest="${appsfolder[10]}/${3}/${4}"
		;;

		* )
			local apk_dest="${appsfolder[2]}/${3}/${4}"
		;;
	esac

	local apk_url="${repo}/${apk_name}"

	if check_sha256sum "${apk_dest}/${4}.apk.gz" "${sha_sum}"; then
		echo -e "\nUp-to-Date from ${repo_p} : ${4}.apk"
	else	echo -e "\nUpdating from ${repo_p}   : ${4}.apk"
		mkdir -p "${apk_dest}"
		rm -f "${apk_dest}/${4}.apk.gz"
		debug_download no_delete "${apk_dest}/${4}.apk" "${apk_url}"

		if check_sha256sum "${apk_dest}/${4}.apk" "${sha_sum}"; then
			echo "	SHA256 hash of ${4}.apk is correct"
			gzip "${apk_dest}/${4}.apk"
		else	echo -e "	SHA256 hash of ${4}.apk is wrong!\
			\n	expected	: ${sha_sum}\
			\n	got		: ${in_checksum}"
			rm -f "${apk_dest}/${4}.apk"
		fi
	fi
}

grab_apk_from_url () {
	local apk_url="${1}"
	local apk_dest="${appsfolder[2]}/${2}/${3}"

	rm -f "${apk_dest}/${3}.apk.gz"

	if [[ -f "${apk_dest}/${3}.apk" ]]; then
		echo -e "\nUpdating from URL         : ${3}.apk"
	else    echo -e "\nDownloading from URL      : ${3}.apk"
		mkdir -p "${apk_dest}"
	fi

	echo "  Checking SHA256 hash not (yet) supported"

	debug_download delete "${apk_dest}/${3}.apk" "${apk_url}" "${apk_dest}/${3}.apk"

	if [[ -f "${apk_dest}/${3}.apk" ]]; then
		gzip "${apk_dest}/${3}.apk"
	else	echo "error downloading ${3}"
	fi
}

grab_apk_from_github () {
	[ "${BP_DEBUG}" = '1' ] && debug_message normal "curl ${curl_opts} -s -N \"https://api.github.com/repos/${1}/releases\""
	local apk_url="$(curl -A "${useragent}" -s "https://api.github.com/repos/${1}/releases/latest" | jq -r '.assets[].browser_download_url')"
	local apk_dest="${appsfolder[2]}/${2}/${3}"

	rm -f "${apk_dest}/${3}.apk.gz"

	if [[ -f "${apk_dest}/${3}.apk" ]]; then
		echo -e "\nUpdating from GitHub      : ${3}.apk"
	else	echo -e "\nDownloading from GitHub   : ${3}.apk"
		mkdir -p "${apk_dest}"
	fi

	echo "	Checking SHA256 hash not (yet) supported"

	debug_download delete "${apk_dest}/${3}.apk" "${apk_url}" "${apk_dest}/${3}.apk"

	if [[ -f "${apk_dest}/${3}.apk" ]]; then
		gzip "${apk_dest}/${3}.apk"
	else	echo "error downloading ${3}"
	fi
}

grab_apk_from_gitlab () {
	[ "${BP_DEBUG}" = '1' ] && debug_message newline "curl ${curl_opts} -s -N \"https://gitlab.com/${1}/-/tags\"" "\n"
	local apk_url="$(curl -A "${useragent}" -s -N "https://gitlab.com/AuroraOSS/AuroraServices/-/tags" | tr '<' '\n' | grep -m 1 -oP '(?<=a href=").*uploads.*apk?(?=")')"
	local apk_url="https://gitlab.com${apk_url}"
	local apk_dest="${appsfolder[2]}/${2}/${3}"

	rm -f "${apk_dest}/${3}.apk.gz"

	if [[ -f "${apk_dest}/${3}.apk" ]]; then
		echo -e "\nUpdating from GitLab      : ${3}.apk"
	else	echo -e "\nDownloading from GitLab   : ${3}.apk"
		mkdir -p "${apk_dest}"
	fi

	echo "	Checking SHA256 hash not (yet) supported"

	debug_download delete "${apk_dest}/${3}.apk" "${apk_url}" "${apk_dest}/${3}.apk"

	if [[ -f "${apk_dest}/${3}.apk" ]]; then
		gzip "${apk_dest}/${3}.apk"
	else	echo "error downloading ${3}"
	fi
}

grab_apk_from_ogapps () {
	case "${4}" in
		19 ) local api_letter=K ;;
		21 ) local api_letter=L ;;
		23 ) local api_letter=M ;;
		24 ) local api_letter=N ;;
		26 ) local api_letter=O ;;
		28 ) local api_letter=P ;;
		29 ) local api_letter=Q ;;
	esac

	case "${1}" in
		"com.google.android.syncadapters.calendar" )
			# use SDK 19 Calendar Syncadapter for SDK 19
			# use SDK 21 Calendar Syncadapter for SDK 21 - 29
			if [ "${4}" -eq 19 ]; then
				local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/15/nodpi/2015080710.apk"
			else
				local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/21/nodpi/2016267990.apk"
			fi
		;;

		"com.google.android.syncadapters.contacts" )
			local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/${4}/nodpi/${4}.apk"
		;;

		"com.google.android.backuptransport" )
			# Use SDK 28 Backuptransport on SDK 29 aswell
			if [ "${4}" -eq 29 ]; then
				local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/28/nodpi/28.apk"
			else
				local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/${4}/nodpi/${4}.apk"
			fi
		;;
	esac

	apk_dest="${appsfolder[6]}/${api_letter}/${2}/${3}"

	if [[ -f "${apk_dest}/${3}.apk.gz" ]]; then
		echo -e "\nUpdating from OpenGApps   : ${3}.apk [${api_letter}]"
		rm -f "${apk_dest}/${3}.apk.gz"
	else	echo -e "\nDownloading from OpenGApps: ${3}.apk [${api_letter}]"
		mkdir -p "${apk_dest}"
	fi

	echo "	Checking SHA256 hash not (yet) supported"

	debug_download delete "${apk_dest}/${3}.apk" "${apk_url}" "${apk_dest}/${3}.apk"

	[ -f "${apk_dest}/${3}.apk" ] && gzip "${apk_dest}/${3}.apk"
}

grab_lib_from_ogapps () {
	case "${3}" in
		arm | x86 )	 LIBD=lib   ;;
		arm64 | x86_64 ) LIBD=lib64 ;;
	esac

	local lib_url="${repo_ogapps}/${3}/raw/master/${LIBD}/${2}/${1}"
	local swp_dest="${appsfolder[8]}/${3}"

	if [[ "${4}" == "true" ]]; then
		local lib_dest="${swp_dest}/${1}_${2}"
	else	lib_dest="${swp_dest}/${1}"
	fi

	if [[ -f "${lib_dest}" ]]; then
		echo -e "\nUpdating from OpenGApps   : ${1} [${2}:${3}]"
	else	echo -e "\nDownloading from OpenGApps: ${1} [${2}:${3}]"
		mkdir -p "${swp_dest}"
	fi

	echo "	Checking SHA256 hash not (yet) supported"

	debug_download delete "${lib_dest}" "${lib_url}" "${lib_dest}"
}

grab_patches () {
	base_url="https://github.com/Lanchon/haystack/blob/master/patches"

	patch_url="${base_url}/${1}?raw=true"
	patch_dst="${CWD}/patcher/dexpatcher/${2}"

	echo -e "\nUpdating from Haystack   : ${2}"
	echo "	Checking SHA256 hash not (yet) supported"

	debug_download delete "${patch_dst}" "${patch_url}""${patch_dst}"
}
