#!/bin/sh -


export LANG=en_US.UTF-8
if ! which sw_vers 2>>/dev/null 1>>/dev/null; then
	_s_path="${HOME}"
	sw_vers(){
		echo '17.0'
	}
	uname(){
		case "${1}" in
			-m)
				echo 'iPhone14,5'
				;;
			-r)
				echo '23.0.0'
				;;
		esac
	}
elif [ -e '/var/mobile' ]; then
	_s_path='/var/mobile'
else
	_s_path="${HOME}"
fi
readonly _command="${0##*/}"
_S='-s '
readonly _uname_m="$(uname -m)"
readonly _uname_r="$(uname -r)"
readonly _system_version="$(sw_vers -productVersion)"
if dpkg -s org.coolstar.sileo 2>>/dev/null 1>>/dev/null; then
	readonly _sileo_version="$(dpkg -s org.coolstar.sileo | grep '^Version: ' | awk -F ' ' '{print $2}')"
else
	readonly _sileo_version='2.5.1'
fi
if which plutil 2>>/dev/null 1>>/dev/null; then
	if ! plutil -key 'CFBundleVersion' "$( [ -e '/rootfs' ] && echo '/rootfs')/System/Library/Frameworks/CoreFoundation.framework/Info.plist" | grep -q '^Error: ' 2>>/dev/null 1>>/dev/null; then
		readonly _core_foundation_version="$(plutil -key 'CFBundleVersion' "$( [ -e '/rootfs' ] && echo '/rootfs')/System/Library/Frameworks/CoreFoundation.framework/Info.plist")"
	else
		readonly _core_foundation_version='2048.100'
	fi
else
	readonly _core_foundation_version='2048.100'
fi

#give you some color see see
RED="$(printf '\033[31m')"
GREEN="$(printf '\033[32m')"
YELLOW="$(printf '\033[33m')"
BLUE="$(printf '\033[34m')"
BOLD="$(printf '\033[1m')"
DIM="$(printf '\033[2m')"
UNDER="$(printf '\033[4m')"
RESET="$(printf '\033[m')"

_print_help(){
	echo "Usage: ${_command} [OPTIONS...]
	-h   --help				Print this help
	-V   --verbose				Print log
	-S   --search				Specify Search
	-s   --source-address			Specify source URL
	-p   --package				Specify package id
	-a   --architecture			Specify packages architecture
	-v   --version				Specify packages version
	-f   --save-path			Specify the path to save the file
	--not-convert-lowercase			Not convert to lower case
Example:
	${_command} -s \"https://invalidunit.github.io/repo/\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -f \"/tmp/\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -S \"debd\" -f \"/tmp/\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -S \"debd\" -a \"iphoneos-arm\" -f \"/tmp/\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -p \"com.nan.debd\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -p \"com.nan.debd\" -f \"/tmp/\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -p \"com.nan.debd\" -a \"iphoneos-arm\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -p \"com.nan.debd\" -a \"iphoneos-arm\" -f \"/tmp/\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -p \"com.nan.debd\" -a \"iphoneos-arm\" -v \"0.1.0\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -p \"com.nan.debd\" -a \"iphoneos-arm\" -v \"0.1.0\" -f \"/tmp/\"
	${_command} -s \"https://invalidunit.github.io/repo/\" -p \"com.nan.debd\" -a \"iphoneos-arm\" -v \"0.1.0\" -f \"/tmp/123.deb\""
}

_echo(){
	if [ -n "${_print_log}" ]; then
		echo "$@"
	fi
}

_randnum(){
	if [ -z "${2}" ]; then
		tr -dc 'A-Za-z0-9' < /dev/urandom | head -c "${1}"
	else
		tr -dc "${1}" < /dev/urandom | head -c "${2}"
	fi
}

_transform_url_encoded(){
	printf %s "${1}" | jq -s -R -r @uri
}

_parse_package(){
	awk '
BEGIN {
    FS=": ";
    OFS=",";
}
{
    sub(/\r$/, "");
    if ($1 == "Package") package = $2;
    if ($1 == "Version") version = $2;
    if ($1 == "Architecture") arch = $2;
    if ($1 == "Package") package_lowercase = $2;
    if ($1 == "Name") name = $2;
    if ($1 == "Filename") filename = $2;
}
/^$/ {
    print package, version, arch, package_lowercase, name, filename;
    package = version = arch = package_lowercase = name = filename = "";
}
END {
    if (package != "" || version != "" || arch != "" || package_lowercase != "" || name != "" || filename != "") {
        print package, version, arch, package_lowercase, name, filename;
    }
}' "${1}" >"${2}"
}

_curl(){
	case "${1}" in
		-c)
			curl --write-out '%{http_code}' --silent --output /dev/null -L "${2}" -H "Host: ${3}" -H "Sec-CH-UA: Sileo;v=${_sileo_version};t=client,unknow;t=jailbreak,procursus;t=distribution" -H "Sec-CH-UA-Model: ${_uname_m}" -H 'Accept-Language: zh-CN,zh-Hans;q=0.9' -H "X-Unique-ID: ${_x_id}" -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept: */*' -H "User-Agent: Sileo/${_sileo_version} CoreFoundation/${_core_foundation_version} Darwin/${_uname_r}" -H 'Connection: keep-alive' -H 'Sec-CH-UA-Platform: iphoneos' -H "X-Machine: ${_uname_m}" -H "X-Firmware: ${_system_version}" -H "Sec-CH-UA-Platform-Version: ${_system_version}" -H 'Sec-CH-UA-Bitness: 64' --compressed
			;;
		-p|-f)
			if [ -n "${_print_log}" ]; then
				echo "[*] curl command: "
				printf '%*s\n' "$(($(tput cols)-1))" | tr ' ' '='
				echo curl ${_S}-L \"${2}\" \-H \"Host: ${3}\" \-H \"Sec-CH-UA: Sileo\;v=${_sileo_version}\;t=client,unknow\;t=jailbreak,procursus\;t=distribution\" \-H \"Sec-CH-UA-Model: ${_uname_m}\" \-H \'Accept-Language: zh-CN,zh-Hans\;q=0.9\' \-H \"X-Unique-ID: ${_x_id}\" \-H \'Accept-Encoding: gzip, deflate, br\' \-H \'Accept: *\/*\' \-H \"User-Agent: Sileo/${_sileo_version} CoreFoundation/${_core_foundation_version} Darwin/${_uname_r}\" \-H \'Connection: keep-alive\' \-H \'Sec-CH-UA-Platform: iphoneos\' \-H \"X-Machine: ${_uname_m}\" \-H \"X-Firmware: ${_system_version}\" \-H \"Sec-CH-UA-Platform-Version: ${_system_version}\" \-H \'Sec-CH-UA-Bitness: 64\' \--compressed \-o \"${4}\"
				printf '%*s\n' "$(($(tput cols)-1))" | tr ' ' '='
			fi
			curl ${_S}-L "${2}" -H "Host: ${3}" -H "Sec-CH-UA: Sileo;v=${_sileo_version};t=client,unknow;t=jailbreak,procursus;t=distribution" -H "Sec-CH-UA-Model: ${_uname_m}" -H 'Accept-Language: zh-CN,zh-Hans;q=0.9' -H "X-Unique-ID: ${_x_id}" -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept: */*' -H "User-Agent: Sileo/${_sileo_version} CoreFoundation/${_core_foundation_version} Darwin/${_uname_r}" -H 'Connection: keep-alive' -H 'Sec-CH-UA-Platform: iphoneos' -H "X-Machine: ${_uname_m}" -H "X-Firmware: ${_system_version}" -H "Sec-CH-UA-Platform-Version: ${_system_version}" -H 'Sec-CH-UA-Bitness: 64' --compressed -o "${4}"
			;;
		*)
			echo 'unknown'
			;;
	esac
}

if [ "${#}" = '0' ]; then
	_print_help
	exit 1
fi
while [ "${#}" -gt '0' ]; do
	case "${1}" in
		-h)
			_print_help
			exit 0
		;;
		-V|--verbose)
			_print_log='1'
			_V='-v '
			unset _S
			_skip='1'
			shift 1
		;;
		-S|--search)
			_search="${2}"
		;;
		--not-convert-lowercase)
			_not_convert_lowercase='1'
			_skip='1'
			shift 1
		;;
		-s|--source-address)
			_url="$(echo "${2}" | sed 's#\/$##')"
		;;
		-p|--package)
			_package="${2}"
		;;
		-a|--architecture)
			_architecture="${2}"
		;;
		-v|--version)
			_version="${2}"
		;;
		-f|--save-path)
			_save_path="${2}"
		;;
		*)
			_skip='1'
			shift 1
		;;
	esac
	if [ "${_skip}" = '1' ]; then
		unset _skip
	else
		shift 2
	fi
done
readonly _x_id="0000$(_randnum '0-9' '4')-000$(_randnum '0-9' '12')E"
_echo "[*] X-Unique-ID: ${_x_id}"
if [ -n "${_save_path}" ]; then
	if echo "${_save_path}" | grep -q ".deb$"; then
		_s_path="${_save_path}"
		_new_path='2'
	else
		_s_path="$(echo "${_save_path}" | sed 's#\/$##')"
		_new_path='1'
	fi
	unset _save_path
else
	_new_path='0'
fi


_tmp_p="/tmp/$(_randnum 'A-Z0-9' '8')-$(_randnum 'A-Z0-9' '4')-$(_randnum 'A-Z0-9' '4')-$(_randnum 'A-Z0-9' '4')-$(_randnum 'A-Z0-9' '12')"
_echo "[*] temporary folder: ${_tmp_p}"
rm -rf "${_tmp_p}"
mkdir -p "${_tmp_p}"
_host="${_url##*://}"
_host="${_host%%/*}"
_echo '[*] now try to download "Packages"...'
if _curl -c "${_url}/Packages.zst" "${_host}" | grep -q '200'; then
	_echo '[*] find "Packages.zst" file'
	_curl -p "${_url}/Packages.zst" "${_host}" "${_tmp_p}/Packages.zst"
	zstd -d "${_tmp_p}/Packages.zst" 1>>/dev/null 2>>/dev/null
	rm ${_V}-f "${_tmp_p}/Packages.zst" &
elif _curl -c "${_url}/Packages.xz" "${_host}" | grep -q '200'; then
	_echo '[*] find "Packages.xz" file'
	_curl -p "${_url}/Packages.xz" "${_host}" "${_tmp_p}/Packages.xz"
	xz -d "${_tmp_p}/Packages.xz"
	rm ${_V}-f "${_tmp_p}/Packages.xz" &
elif _curl -c "${_url}/Packages.bz2" "${_host}" | grep -q '200'; then
	_echo '[*] find "Packages.bz2" file'
	_curl -p "${_url}/Packages.bz2" "${_host}" "${_tmp_p}/Packages.bz2"
	bzip2 -d "${_tmp_p}/Packages.bz2"
	rm ${_V}-f "${_tmp_p}/Packages.bz2" &
elif _curl -c "${_url}/Packages.gz" "${_host}" | grep -q '200'; then
	_echo '[*] find "Packages.gz" file'
	_curl -p "${_url}/Packages.gz" "${_host}" "${_tmp_p}/Packages.gz"
	gzip -d "${_tmp_p}/Packages.gz"
	rm ${_V}-f "${_tmp_p}/Packages.gz" &
elif _curl -c "${_url}/Packages" "${_host}" | grep -q '200'; then
	_echo '[*] find "Packages" file'
	_curl -p "${_url}/Packages" "${_host}" "${_tmp_p}/Packages"
else
	echo '[*] Not found any "Package" file'
	exit 1
fi
if [ -f "${_tmp_p}/Packages" ]; then
	_echo '[*] Start converting to csv'
	sed -i. 's#,##g' "${_tmp_p}/Packages"
	_parse_package "${_tmp_p}/Packages" "${_tmp_p}/Packages.csv"
	awk 'BEGIN {FS=OFS=","} {$4=tolower($4)}1' "${_tmp_p}/Packages.csv" >"${_tmp_p}/Packages-orig.csv"
	sort -rk2n "${_tmp_p}/Packages-orig.csv" >"${_tmp_p}/Packages.csv"
	if [ -z "${_package}" ]; then
		if [ -n "${_architecture}" ]; then
			mv "${_tmp_p}/Packages.csv" "${_tmp_p}/Packages-all-arch.csv"
			awk -v architecture="${_architecture}" -F ',' '$3==architecture {print}' "${_tmp_p}/Packages-all-arch.csv" >"${_tmp_p}/Packages.csv"
		fi
		sed -i.tmp '1i Package,Version,Architecture,Package_lowercase,Name,Filename' "${_tmp_p}/Packages.csv"
		printf '%*s\n' "$(($(tput cols)-1))" | tr ' ' '='
		awk -F ',' 'BEGIN {OFS=","} {print $1,$5,$2,$3}' "${_tmp_p}/Packages.csv" >"${_tmp_p}/Packages-column.csv"
		if [ -z "${_search}" ]; then
			awk -F ',' 'BEGIN {OFS=","; print "NR,Package,Name,Version,Architecture"} NR>1 {print NR-1 "," $0}' "${_tmp_p}/Packages-column.csv" | column -t -s,
		else
			awk -F ',' 'BEGIN {OFS=","; print "NR,Package,Name,Version,Architecture"} NR>1 {print NR-1 "," $0}' "${_tmp_p}/Packages-column.csv" | column -t -s, | sed -n '1p'
			awk -F ',' 'BEGIN {OFS=","; print "NR,Package,Name,Version,Architecture"} NR>1 {print NR-1 "," $0}' "${_tmp_p}/Packages-column.csv" | column -t -s, | grep -i --color=auto "${_search}"
		fi
		printf '%*s\n' "$(($(tput cols)-1))" | tr ' ' '='
		read -p "Please enter number to download: " _package
		if [ -n "$(echo "${_package}" | tr -d '0-9')" ]; then
			echo "${RED}Error: invalid input...${RESET}"
			rm -rf "${_tmp_p}"
			exit 1
		fi
		_package="$((_package+1))"
		if [ "${_package}" -gt "$(wc -l <"${_tmp_p}/Packages.csv")" ]; then
			echo "${RED}Error: No row exists...${RESET}"
			rm -rf "${_tmp_p}"
			exit 1
		fi
		_package_info="$(sed -n "${_package}p" "${_tmp_p}/Packages.csv")"
		if [ -z "${_package_info}" ]; then
			_exit='1'
		fi
	else
		if [ -n "${_architecture}" ]; then
			if grep -q "${_package}," "${_tmp_p}/Packages.csv"; then
				if [ -z "${_not_convert_lowercase}" ]; then
					_package_info="$(awk -v package="${_package}" -v architecture="${_architecture}" -F ',' '$4==package && $3==architecture {print}' "${_tmp_p}/Packages.csv")"
				else
					_package_info="$(awk -v package="${_package}" -v architecture="${_architecture}" -F ',' '$1==package && $3==architecture {print}' "${_tmp_p}/Packages.csv")"
				fi
				case "$(echo "${_package_info}" | wc -l)" in
					0)
						_exit='1'
						;;
					1)
						sleep 0
						;;
					*)
						_package_info="$(echo "${_package_info}" | sed -n '1p')"
						;;
				esac
			else
				_exit='1'
			fi
		else
			i='1'
			i_max="$(grep "${_package}," "${_tmp_p}/Packages.csv" | awk -F ',' '{print $3}' | sort -k2n | uniq | wc -l)"
			while [ "${i}" -le "${i_max}" ]; do
				_architecture="$(grep "${_package}," "${_tmp_p}/Packages.csv" | awk -F ',' '{print $3}' | sort -k2n | uniq | sed -n "${i}p")"
				if [ -z "${_not_convert_lowercase}" ]; then
					_package_info_1="$(awk -v package="${_package}" -v architecture="${_architecture}" -F ',' '$4==package && $3==architecture {print}' "${_tmp_p}/Packages.csv")"
				else
					_package_info_1="$(awk -v package="${_package}" -v architecture="${_architecture}" -F ',' '$1==package && $3==architecture {print}' "${_tmp_p}/Packages.csv")"
				fi
				case "$(echo "${_package_info_1}" | wc -l)" in
					0)
						_exit='1'
						;;
					1)
						sleep 0
						;;
					*)
						_package_info_1="$(echo "${_package_info_1}" | sed -n '1p')"
						;;
				esac
				_package_info="${_package_info}
${_package_info_1}"
				i="$((i+1))"
			done
			unset _package_info_1 i i_max
			_package_info="$(echo "${_package_info}" | sed '1d')"
		fi
	fi
	if [ "${_package_info}" = '' ]; then
		_exit='1'
	fi
	if [ ! "${_exit}" = '1' ]; then
		if [ -n "${_print_log}" ]; then
			echo '[*] all package info:'
			printf '%*s\n' "$(($(tput cols)-1))" | tr ' ' '-'
			echo "$(echo "${_package_info}" | column -t -s,)"
			printf '%*s\n' "$(($(tput cols)-1))" | tr ' ' '-'
		fi
		i='1'
		i_max="$(echo "${_package_info}" | wc -l)"
		while [ "${i}" -le "${i_max}" ]; do
			_echo "[*] now: $(echo "${_package_info}" | sed -n "${i}p" | column -t -s,)"
			_package="$(echo "${_package_info}" | sed -n "${i}p" | awk -F ',' '{print $1}')"
			_version="$(echo "${_package_info}" | sed -n "${i}p" | awk -F ',' '{print $2}')"
			_architecture="$(echo "${_package_info}" | sed -n "${i}p" | awk -F ',' '{print $3}')"
			_file_name="$(echo "${_package_info}" | sed -n "${i}p" | awk -F ',' '{print $6}')"
			#_file_name="$(echo "${_file_name}" | sed 's#\ #%20#g')"
			_file_name="$(_transform_url_encoded "${_file_name}" | sed 's#%2F#/#g')"
			_file_n="$(_randnum '20')"
			_curl -f "${_url}/${_file_name}" "${_host}" "${_tmp_p}/${_file_n}.deb"
			if file "${_tmp_p}/${_file_n}.deb" | grep -q " Debian binary package "; then
				case "${_new_path}" in
					0)
						mkdir -p "${_s_path}/Downloads/deb/"
						_new_path_1="${_s_path}/Downloads/deb/${_package}_${_version}_${_architecture}.deb"
						;;
					1)
						mkdir -p "${_s_path}"
						_new_path_1="${_s_path}/${_package}_${_version}_${_architecture}.deb"
						;;
					2)
						mkdir -p "${_s_path%/*}"
						_new_path_1="${_s_path}"
						;;
				esac
				if [ -f "${_new_path_1}" ]; then
					_new_path_1="${_new_path_1%\.deb}_$(_randnum '20').deb"
				fi
				mv ${_V} "${_tmp_p}/${_file_n}.deb" "${_new_path_1}"
				if id -u | grep -q '^0$'; then
					if [ "${_s_path}" = '/var/mobile' ]; then
						chown -R "mobile:mobile" "${_s_path}/Downloads/deb/"
						chown -R "mobile:mobile" "${_new_path_1}"
					fi
				fi
				echo "${_new_path_1}"
			else
				echo "[x] Error: The downloaded file(${_package}_${_version}_${_architecture}) is corrupt or the download failed..."
			fi
			unset _package _version _architecture _new_path_1 _file_n _file_name
			i="$((i+1))"
		done
	else
		echo '[x] Error: The requested package cannot be found in the list...'
	fi
fi
if [ -z "${_print_log}" ]; then
	rm -rf "${_tmp_p}"
fi
exit 0
