#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2026 Bryan Joshua Pedini

# fake dnf (unit tests). FAKE_DNF_MAJOR=4|5 picks the output dialect; FAKE_DNF_CHECK_RC=0|1 simulates
# "no updates" / an error; FAKE_DNF_CHECK=obsoletes replays a check-update with only an
# "Obsoleting Packages" section; FAKE_DNF_REMOVE_REFUSE=1 makes `--assumeno remove` fail;
# removal tables: see the --assumeno remove branch.
# shellcheck source=../fakelib.bash
. "${BASH_SOURCE[0]%/*}/../fakelib.bash"
# shellcheck source=../../data/rpm/db.bash
. "$FAKE_DATA/rpm/db.bash"
fake_log "$@"
D=$FAKE_DATA/dnf
major=${FAKE_DNF_MAJOR:-4}
pos=()
for a in "$@"; do case $a in -*) ;; *) pos+=("$a") ;; esac; done
installed() { [[ -n ${EVR[$1]:-} ]] && ! fake_purged "$1"; }
case " $* " in
*' --version '*) if ((major == 5)); then echo "dnf5 version 5.4.3.0"; else echo "4.14.0"; fi ;;
*' makecache '*)
	rc=$(fake_rc FAKE_DNF_MAKECACHE_RC 0)
	((rc == 0)) || echo "Error: Failed to download metadata for repo 'su-dummy': Cannot download repomd.xml" >&2
	exit "$rc"
	;;
*' check-update '*)
	rc=$(fake_rc FAKE_DNF_CHECK_RC 100)
	f=$D/check-update-dnf$major.txt
	[[ ${FAKE_DNF_CHECK:-} != obsoletes ]] || f=$D/check-update-obsoletes.txt
	case $rc in
	100)
		while IFS= read -r line; do
			read -r na _ <<<"$line"
			[[ -n $na ]] && fake_purged "${na%.*}" && continue
			printf '%s\n' "$line"
		done <"$f"
		;;
	1) echo "Error: Failed to download metadata for repo 'baseos'" >&2 ;;
	esac
	exit "$rc"
	;;
*' repoquery '*)
	p=${pos[-1]}
	case " $* " in
	*' --upgrades '*) case $p in su-dummy-[abc]) printf 'skeptical-updater dummy %s (v2.0)\n' "$p"; ((major == 5)) || echo ;; esac ;;
	*) case $p in su-dummy-new) printf 'skeptical-updater dummy su-dummy-new (v1.0)\n' ;; esac ;;
	esac
	exit 0
	;;
*' info '*)
	p=${pos[-1]}
	if [[ -f $D/info-$p.txt ]]; then cat "$D/info-$p.txt"; else
		echo "Error: No matching Packages to list" >&2
		exit 1
	fi
	;;
*' --assumeno '*remove*)
	# the removal table: the target, its dependents (su-dummy-a for su-dummy-b; FAKE_DNF_DEPENDENT=
	# "pkg:other"), its unused dependencies (FAKE_DNF_UNUSED="pkg:dep"); FAKE_DNF_WRAP wraps those rows
	p=${pos[-1]}
	if [[ -n ${FAKE_DNF_REMOVE_REFUSE:-} ]]; then
		echo "Error: Problem: The operation would result in removing the following protected packages: $p"
		exit 1
	fi
	if ! installed "$p"; then
		echo "No match for argument: $p"
		echo "No packages marked for removal."
		echo "Dependencies resolved."
		echo "Nothing to do."
		echo "Complete!"
		exit 0
	fi
	dependent=() unused=()
	[[ $p != su-dummy-b ]] || ! installed su-dummy-a || dependent+=(su-dummy-a)
	for r in ${FAKE_DNF_DEPENDENT:-}; do [[ ${r%%:*} == "$p" ]] && dependent+=("${r#*:}"); done
	for r in ${FAKE_DNF_UNUSED:-}; do [[ ${r%%:*} == "$p" ]] && unused+=("${r#*:}"); done
	row() { # row NAME
		if ((major == 5)); then
			if [[ -n ${FAKE_DNF_WRAP:-} && $1 != "$p" ]]; then
				echo " $1"
				echo "                                   noarch 0:1.0-1 <unknown>   15.0   B"
			else
				echo " $1 noarch 0:1.0-1 <unknown>   15.0   B"
			fi
		elif [[ -n ${FAKE_DNF_WRAP:-} && $1 != "$p" ]]; then
			printf ' %s\n' "$1"
			printf '                      noarch           1.0-1            @System            15\n'
		else
			printf ' %-20s noarch           1.0-1            @System            15\n' "$1"
		fi
	}
	if ((major == 5)); then
		echo "Package     Arch   Version Repository      Size"
	else
		echo "Dependencies resolved."
		echo "================================================================================"
		echo " Package              Architecture     Version          Repository         Size"
		echo "================================================================================"
	fi
	echo "Removing:"
	row "$p"
	if ((${#dependent[@]})); then
		echo "Removing dependent packages:"
		for r in "${dependent[@]}"; do row "$r"; done
	fi
	if ((${#unused[@]})); then
		echo "Removing unused dependencies:"
		for r in "${unused[@]}"; do row "$r"; done
	fi
	echo
	n=$((1 + ${#dependent[@]} + ${#unused[@]}))
	if ((major == 5)); then
		echo "Transaction Summary:"
		echo " Removing:           $n packages"
		echo "Operation aborted by the user."
	else
		echo "Transaction Summary"
		echo "================================================================================"
		echo "Remove  $n Packages"
		echo
		echo "Operation aborted."
	fi
	exit 1
	;;
*' upgrade '*) exit "$(fake_rc FAKE_DNF_UPGRADE_RC 0)" ;;
*' remove '*)
	fake_mark_purged "${pos[@]:1}"
	exit 0
	;;
*)
	echo "fake dnf: unhandled: $*" >&2
	exit 99
	;;
esac
