#!/bin/bash
# AppFetch - Turann & Randy420

ver="0.8"

print_message() {
	for message in "$@"; do
		echo -e "$message"
		#sleep 0.009
	done
}

print_help() {
    echo ""
    echo "AppFetch - Turann & Randy420"
    echo ""
    echo "Usage: appfetch [OPTIONS]"
    echo "Options:"
    echo "  -a, --app <name>     Specify the name of the app to search."
    echo "  -r, --repo <1-5>     Specify the repository to search for the app."
    echo "  -h, --help           Show this help message and exit."
    echo ""
    echo "Available Repositories:"
    echo "  1) iPhoneCake"
    echo "  2) ++ App"
    echo "  3) Cypwn API"
    echo "  4) AppleTesters.org"
    echo "  5) StarFiles (Matches usually have HUNDREDS of results)"
}

check_invalid_appID() {
	toCheck="${1}"
	result=$(uicache --list "${toCheck}")
	if [[ $result =~ "Invalid appID provided:" ]]; then
		unset result
	fi
	echo "$result"
}

search_app() {
	app_name="${1}"
	if [ "$download_location" -eq 5 ]; then
		read -p "		Limit the amount of results
		1) Yes
		2) No
		" limit_search

		limit_param=""
		if [[ $limit_search -eq 1 ]]; then
			read -p "Number of results: " search_limit
			limit_param="&limit=${search_limit}"
		fi

		url="https://api2.starfiles.co/files?public=true&search=${app_name}${limit_param}&group=hash&collapse=true&extension=ipa&sort=popular"
		response=$(curl -s "$url")

		app_count=$(echo "${response}" | jq -r 'length')

		if [[ $app_count -eq 0 ]]; then
			print_message "Application not found"
			exit
		fi

		for ((i = 0; i < app_count; i++)); do
			app_id=$(echo "${response}" | jq -r ".[$i].id")
			app_name=$(echo "${response}" | jq -r ".[$i].name")
			app_downloads=$(echo "${response}" | jq -r ".[$i].downloads")
			app_views=$(echo "${response}" | jq -r ".[$i].views")

			print_message "\n\n\t-- App Number: $((i + 1)) --"
			print_message "Application name: ${app_name}"
			print_message "Downloads: ${app_downloads}"
			print_message "Views: ${app_views}"
		done
		return
	fi

	app_count=0
	response=""
	if [ "$download_location" -eq 1 ]; then
		url="https://apiv2.iphonecake.com/appcake/appcake_api/spv6/appsearch_r.php?device=1&q=${app_name}&p=0"
	elif [ "$download_location" -eq 2 ]; then
		url="https://api.ipahub.com/search_tweaks.php?key=${app_name}"
	elif [ "$download_location" -eq 3 ]; then
		read -p "		1) Troll Store Only
		2) Non Troll Store
		3) Both
		" trollstore_option
		trollstore_param=""
		if [[ $trollstore_option -eq 1 ]]; then
			trollstore_param="&trollstore=YES"
		elif [[ $trollstore_option -eq 2 ]]; then
			trollstore_param="&trollstore=NO"
		fi
		url="https://api.cypwn.xyz/@ipas/search?name=${app_name}${trollstore_param}"
    elif [ "$download_location" -eq 4 ]; then
        json_url="https://api2.starfiles.co/repo_search?url=https://raw.githubusercontent.com/apptesters-org/Repo/main/apps.json&query=${app_name}"
        response=$(curl -s "$json_url")
        
        app_count=$(echo "${response}" | jq -r '.apps | length')

        if [[ $app_count -eq 0 ]]; then
            print_message "Application not found"
            exit
        fi

        for ((i = 0; i < app_count; i++)); do
            app_name=$(echo "${response}" | jq -r ".apps[$i].name")
            app_bundle_id=$(echo "${response}" | jq -r ".apps[$i].bundleID")
            app_version=$(echo "${response}" | jq -r ".apps[$i].version")
            app_version_date=$(echo "${response}" | jq -r ".apps[$i].versionDate")
            app_full_date=$(echo "${response}" | jq -r ".apps[$i].fullDate")
            app_size=$(echo "${response}" | jq -r ".apps[$i].size")
            download_url=$(echo "${response}" | jq -r ".apps[$i].down")

            print_message "\n\n\t-- App Number: $((i + 1)) --"
            print_message "Application name: ${app_name}"
            print_message "Bundle ID: ${app_bundle_id}"
            print_message "Version: ${app_version}"
            print_message "Version Date: ${app_version_date}"
#            print_message "Full Date: ${app_full_date}"
            print_message "Size: ${app_size}"
#            print_message "Download URL: ${download_url}"
        done
        return
    fi

	if [ "$download_location" -eq 1 ] || [ "$download_location" -eq 2 ] || [ "$download_location" -eq 3 ]; then
		response=$(curl -s -X GET -H "x-api-key: appfetch-d405-4859-a784-a82a6b5c9f75" "${url}")

		if [ "$download_location" -eq 1 ] || [ "$download_location" -eq 2 ]; then
			app_count=$(echo "${response}" | jq -r '.list | length')
		else
			app_count=$(echo "${response}" | jq -r '.total')
		fi

		if [[ $app_count -eq 0 ]]; then
			print_message "Application not found"
			exit
		fi

		for (( i=0; i<app_count; i++ )); do
			if [ "$download_location" -eq 1 ] || [ "$download_location" -eq 2 ]; then
				app_name=$(echo "${response}" | jq -r ".list[$i].name")
				app_version=$(echo "${response}" | jq -r ".list[$i].ver")
				app_id=$(echo "${response}" | jq -r ".list[$i].id")
			else
				app_name=$(echo "${response}" | jq -r ".ipas[$i].name")
				app_version=$(echo "${response}" | jq -r ".ipas[$i].version")
				app_id=$(echo "${response}" | jq -r ".ipas[$i].id")
			fi

			hyphens=$(printf '%*s' "$((${#app_name}+${#app_version}+2))" | tr ' ' '-')

			print_message "\n\n\t-- App Number: $((i+1)) --"
			print_message "Application name: ${app_name}"
			print_message "Application Version: v${app_version}"
			print_message "Application ID: ${app_id}"
			#print_message "Download URL: ${download_url}"
			print_message "$hyphens"
		done
		return
	fi
}

download_app() {
	app_number="${1}"
	if [ "$download_location" -eq 5 ]; then
		ids=$(echo "${response}" | jq -r ".[${app_number}].id")
		app_name=$(echo "${response}" | jq -r ".[${app_number}].name")

		download_link="https://download.starfiles.co/${ids}"

		print_message "Downloading ${app_name} from StarFiles..."
		outDir="/var/mobile/appFetch/"
		if [[ ! -d ${outDir} ]]; then
			mkdir -p ${outDir}
		fi

		wget --show-progress "${download_link}" -O "${outDir}${app_name}"

		if [[ -f "${outDir}${app_name}" ]]; then
			print_message "${app_name} successfully downloaded to ${outDir}"
		else
			print_message "Failed to download ${app_name}"
		fi
		return
	fi
	if [ "$download_location" -eq 1 ] || [ "$download_location" -eq 2 ]; then
		if [ "$download_location" -eq 1 ]; then
			app_name=$(echo "${response}" | jq -r ".list[${app_number}].name")
			app_version=$(echo "${response}" | jq -r ".list[${app_number}].ver")
			app_id=$(echo "${response}" | jq -r ".list[${app_number}].id")
			url="https://apiv2.iphonecake.com/appcake/appcake_api/ipastore_ios_link.php?type=1&id=${app_id}"
		elif [ "$download_location" -eq 2 ]; then
			app_name=$(echo "${response}" | jq -r ".list[${app_number}].name")
			app_version=$(echo "${response}" | jq -r ".list[${app_number}].ver")
			app_id=$(echo "${response}" | jq -r ".list[${app_number}].id")
			url="https://apiv2.iphonecake.com/appcake/appcake_api/ipastore_ios_link.php?type=2&id=${app_id}"
		fi

		response=$(curl -s -X GET -H "${headers[@]}" -d "${payload}" "${url}")
		download_lmk=$(echo "${response}" | jq -r '.link' | tr -d '"' | sed 's/^[[:space:]]*//')
		outDir="/var/mobile/appFetch/"

		if [[ ! -d ${outDir} ]]; then
			mkdir -p ${outDir}
		fi

		print_message "Downloading ${app_name}..."
		wget --show-progress "${download_lmk}" -O "${outDir}${app_name}.ipa"

		if [[ -f "${outDir}${app_name}.ipa" ]]; then
			print_message "${app_name} successfully downloaded to ${outDir}"
		else
			print_message "Failed to download ${app_name}"
		fi
	elif [ "$download_location" -eq 3 ]; then
		app_name=$(echo "${response}" | jq -r ".ipas[${app_number}].name")
		download_url=$(echo "${response}" | jq -r ".ipas[${app_number}].download_url")
		outDir="/var/mobile/appFetch/"

		if [[ ! -d ${outDir} ]]; then
			mkdir -p ${outDir}
		fi

		print_message "Downloading ${app_name} from Cypwn API..."
		wget --show-progress "${download_url}" -O "${outDir}${app_name}.ipa"

		if [[ -f "${outDir}${app_name}.ipa" ]]; then
			print_message "${app_name} successfully downloaded to ${outDir}"
		else
			print_message "Failed to download ${app_name}"
		fi
	elif [ "$download_location" -eq 4 ]; then
		app_name=$(echo "${response}" | jq -r ".apps[${app_number}].name")
		download_url=$(echo "${response}" | jq -r ".apps[${app_number}].downloadURL")

		outDir="/var/mobile/appFetch/"
		if [[ ! -d ${outDir} ]]; then
			mkdir -p ${outDir}
		fi

		print_message "Downloading ${app_name} from Custom JSON..."
		wget --show-progress "${download_url}" -O "${outDir}${app_name}.ipa"

		if [[ -f "${outDir}${app_name}.ipa" ]]; then
			print_message "${app_name} successfully downloaded to ${outDir}"
		else
			print_message "Failed to download ${app_name}"
		fi
	else
		print_message "Invalid download location"
		exit
	fi
}

app_fetch_main() {
	clear
	print_message "AppFetch $ver"

	app_name=""
	download_location=""

	# Check for command line arguments
	while [[ $# -gt 0 ]]; do
		key="$1"

		case $key in
			-h|--help)
				print_help
				exit
				;;
			-a|--app)
				app_name="$2"
				shift
				;;
			-r|--repo)
				download_location="$2"
				shift
				;;
			*)
				print_message "Invalid argument: $key"
				exit 1
				;;
		esac
		shift
	done

	if [[ -z "$app_name" && -z "$download_location" ]]; then
		read -rp "
Enter the name of the app to search: " app_name

		while :
		do
		read -rp "	Which type of IPA would you like to download?
	1) iPhoneCake
	2) ++ App
	3) Cypwn API
	4) AppleTesters.org
	5) StarFiles (Matches usually have HUNDREDS of results)
	" download_location

			if [[ $download_location -lt 1 || $download_location -gt 5 ]]; then
				print_message "Invalid Selection!"
				continue
			fi
			break
		done
	elif [[ -z "$app_name" ]]; then
		read -rp "
Enter the name of the app to search: " app_name
	elif [[ -z "$download_location" ]]; then
		while :
		do
			read -rp "Which type of IPA would you like to download?
			1) iPhoneCake
			2) ++ App
			3) Cypwn API
			4) AppleTesters.org
			5) StarFiles (Matches usually have HUNDREDS of results)
			" download_location

			if [[ $download_location -lt 1 || $download_location -gt 5 ]]; then
				print_message "Invalid Selection!"
				continue
			fi
			break
		done
	fi

	payload=""
	headers=(
		"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
		"User-Agent: appcakej/7.2.2 (iPhone; iOS 14.8; Scale/3.00)"
		"Connection: close"
		"Host: api.iphonecake.com"
		"Accept-Encoding: gzip, deflate"
		"Cache-Control: max-age=0"
	)

	search_app "$app_name"

	while :
	do
		read -p "
Enter the number of the app you want to download: " app_number

		if ! [[ "$app_number" =~ ^[0-9]+$ ]]; then
			print_message "Invalid input. Please enter a number."
			continue
		fi

		if [ "$app_number" -lt 1 ] || [ "$app_number" -gt "$app_count" ]; then
			print_message "Invalid input. Please enter a number between 1 and $app_count."
			continue
		fi
		break
	done

	app_number=$((app_number-1))
	download_app "$app_number"
}

app_fetch_main "$@"
