#!/bin/bash
###############################################################################
#                                                                             #
# Pakfire - The IPFire package management system                              #
# Copyright (C) 2021 Pakfire development team                                 #
#                                                                             #
# This program is free software: you can redistribute it and/or modify        #
# it under the terms of the GNU General Public License as published by        #
# the Free Software Foundation, either version 3 of the License, or           #
# (at your option) any later version.                                         #
#                                                                             #
# This program is distributed in the hope that it will be useful,             #
# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
# GNU General Public License for more details.                                #
#                                                                             #
# You should have received a copy of the GNU General Public License           #
# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
#                                                                             #
###############################################################################

error() {
	echo "$@" >&2
}

FILTER_WEAK_PROVIDES='BEGIN { START=0; }
	/Version definitions:/ { START=1; }
	/^[0-9]/ && (START==1) { print $4; }
	/^$/ { START=0; }'

pkgconfig_provides() {
	local file="${1}"

	local n r v
	while read -r n r v; do
		echo "pkgconfig(${n}) ${r} ${v}"
	done < <(pkg-config --print-provides "${file}" 2>/dev/null)

	return 0
}

shared_object_provides() {
	local file="${1}"

	# Get SONAME
	local soname="$(objdump -p "${file}" 2>/dev/null | awk '/SONAME/ { print $2 }')"

	# If the files does not have a SONAME, we will simply use the basename
	if [ -z "${soname}" ]; then
		soname="$(basename "${file}")"
	fi

	local suffix

	# Is this a 64 bit file?
	if file -L "${file}" 2>/dev/null | grep -q "ELF 64-bit"; then
		suffix="(64bit)"

		echo "${soname}()${suffix}"
	else
		echo "${soname}"
	fi

	# Find weak symbol provides
	while read -r symbol; do
		echo "${soname}(${symbol})${suffix}"
	done < <(objdump -p "${file}" 2>/dev/null | awk "${FILTER_WEAK_PROVIDES}")

	return 0
}

main() {
	local buildroot="${1}"

	# Check if BUILDROOT exists
	if [ ! -d "${buildroot}" ]; then
		error "BUILDROOT (${buildroot}) does not exist"
		return 1
	fi

	local file
	while read -r file; do
		# Filter out what we don't need
		case "${file}" in
			# Debug files
			/usr/lib/debug/*|/usr/src/debug/*)
				continue
				;;

			# Skip shared objects in Python directories
			/usr/lib*/python*/*.so*)
				continue
				;;

			# Skip gconv
			/usr/lib*/gconv/*)
				continue
				;;
		esac

		# Make the full path
		local path="${buildroot}${file}"

		# Process special files
		case "${file}" in
			# pkg-config
			*.pc)
				# Query provides of the package
				pkgconfig_provides "${path}"
				;;

			# Shared objects
			*.so|*.so.*)
				# Skip symlinks
				if [ -L "${path}" ]; then
					continue
				fi

				shared_object_provides "${path}"
				;;
		esac
	done | sort -u

	return 0
}

main "$@" || exit $?
