#!/bin/sh

. /usr/share/libubox/jshn.sh

action=$1
shift

if [ -f /usr/bin/apk ]; then
	ipkg_bin="apk"
else
	ipkg_bin="opkg"
fi

case "$action" in
	list-installed)
		if [ $ipkg_bin = "apk" ]; then
      $ipkg_bin query --fields all --format json --installed --from system \* 2>/dev/null
		else
			cat /usr/lib/opkg/status
		fi
	;;
	list-available)
		if [ $ipkg_bin = "apk" ]; then
      $ipkg_bin query --fields all --format json --available \* 2>/dev/null
		else
			lists_dir=$(sed -rne 's#^lists_dir \S+ (\S+)#\1#p' /etc/opkg.conf /etc/opkg/*.conf 2>/dev/null | tail -n 1)
			find "${lists_dir:-/usr/lib/opkg/lists}" -type f '!' -name '*.sig' | xargs -r gzip -cd
		fi
	;;
	install|update|upgrade|upgradeall|remove)
		(
			cmd="$ipkg_bin"

			# The apk package manager uses distinct commands for installing and removing packages.
			if [ $ipkg_bin = "apk" ]; then
				case "$action" in
					install)
						action="add"
					;;
					remove)
						action="del"
					;;
				esac
			fi

			# APK have --autoremove enabled by default and
			# --force-removal-of-dependent-packages as -r option
			if [ $ipkg_bin = "apk" ]; then
				while [ -n "$1" ]; do
					case "$1" in
            --autoremove)
              # Just shift and do nothing.
              # 'apk del' already cleans up orphaned dependencies by default.
              shift
              ;;
						--force-removal-of-dependent-packages)
							cmd="$cmd -r"
							shift
						;;
						--force-overwrite)
							cmd="$cmd $1"
							shift
						;;
						-*)
							shift
						;;
						*)
							break
						;;
					esac
				done
			else
				while [ -n "$1" ]; do
					case "$1" in
						--autoremove|--force-overwrite|--force-removal-of-dependent-packages)
							cmd="$cmd $1"
							shift
						;;
						-*)
							shift
						;;
						*)
							break
						;;
					esac
				done
			fi

			if flock -x 200; then
				pkmcmd="$cmd $action $@"
				if [ $action == "upgradeall" ]; then
					$cmd update </dev/null >/tmp/ipkg.out 2>/tmp/ipkg.err
					code=$?
					if [ $code == 0 ]; then
						. /etc/profile.d/opkg.sh
						if [[ "$(cat `opkg export au`)" ]] && lock -n /var/lock/opkg-upgrade; then
						 opkg upgr </dev/null >>/tmp/ipkg.out 2>>/tmp/ipkg.err
						 code=$?
						 lock -u /var/lock/opkg-upgrade
						else
							echo "🎉 所有软件包已是最新~" >>/tmp/ipkg.out
							code=0
						fi
					fi
				else
					$cmd $action "$@" </dev/null >/tmp/ipkg.out 2>/tmp/ipkg.err
					code=$?
				fi
				pkgn="$(echo $@ | cut -d - -f 3-)"
				case "$action" in
					install|upgrade)
					if [ "$(opkg list-installed | cut -f 1 -d ' ' | grep -w $@)" ]; then
							rm -f /tmp/ipkg.err
							([ -f /etc/profile.d/opkg.sh ] && . /etc/profile.d/opkg.sh && opkg save) &
					fi
					;;
					remove)
						if [ ! "$(opkg list-installed | cut -f 1 -d ' ' | grep -w $@)" ]; then
							rm -f /tmp/ipkg.err
							([ -f /etc/profile.d/opkg.sh ] && . /etc/profile.d/opkg.sh && opkg save) &
						fi
					;;
				esac
				stderr=$(cat /tmp/ipkg.err)
				[ -n "$stderr" ] || {
					echo "🎉 已完成, 请关闭本窗口~" >>/tmp/ipkg.out
					code=0
				}
				stdout=$(cat /tmp/ipkg.out)
			else
				code=255
				stderr="Failed to acquire lock"
			fi

			json_init
			json_add_int code $code
			[ -n "$pkmcmd" ] && json_add_string pkmcmd "$pkmcmd"
			[ -n "$stdout" ] && json_add_string stdout "$stdout"
			[ -n "$stderr" ] && json_add_string stderr "$stderr"
			json_dump
		) 200>/tmp/ipkg.lock

		rm -f /tmp/ipkg.lock /tmp/ipkg.err /tmp/ipkg.out
	;;
	*)
		echo "Usage: $0 {list-installed|list-available|update}" >&2
		echo "       $0 {install|upgrade|upgradeall|remove} pkg[ pkg...]" >&2
		exit 1
	;;
esac
