#!/bin/bash

## Copyright (C) 2026 - 2026 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

## AI-Assisted

## Verify the shipped VBoxGuestAdditions.iso against the committed upstream
## SHA256SUMS and MD5SUMS, fail closed. Called from BOTH the genmkfile build
## hook (debian/make-helper-overrides.bsh, the 'dist' path) and debian/rules
## (the 'dpkg-buildpackage' path), so every build route re-verifies the ISO.

set -o errexit
set -o nounset
set -o pipefail
set -o errtrace
shopt -s inherit_errexit
shopt -s shift_verbose

exit_with_error() {
   printf '%s\n' "$0: ERROR: $*" >&2
   exit 1
}

## Run from the package root regardless of caller CWD.
script_dir="$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")")"
cd -- "${script_dir}/.."

iso_dir="usr/share/virtualbox"
iso_file="${iso_dir}/VBoxGuestAdditions.iso"

## Verify one checksum flavor of the shipped ISO against an upstream sums file.
##
## Upstream lists the ISO under its VERSIONED name
## (VBoxGuestAdditions_<version>.iso), while this package ships it unversioned
## (VBoxGuestAdditions.iso). core.symlinks=false rules out bridging the two
## names with an in-repo symlink, and 'sha256sum --check --ignore-missing'
## would silently verify NOTHING on that name mismatch (exit 0). So pull the
## expected hash out of the single matching line and compare it against the
## actual shipped file. Fail closed on a missing file, a missing/duplicate
## line, or a hash mismatch.
verify_one() {
   local tool sums_file expected_hash actual_hash
   local -a matched_lines

   tool="$1"
   sums_file="$2"

   test -f "${sums_file}" || exit_with_error "checksum file missing: '${sums_file}'"
   test -f "${iso_file}"  || exit_with_error "ISO file missing: '${iso_file}'"

   mapfile -t matched_lines < <(grep -E ' \*?VBoxGuestAdditions_[^ ]+\.iso$' -- "${sums_file}" || true)
   [ "${#matched_lines[@]}" = "1" ] || exit_with_error \
      "expected exactly one 'VBoxGuestAdditions_*.iso' line in '${sums_file}', found '${#matched_lines[@]}'."

   expected_hash="${matched_lines[0]%% *}"
   [ -n "${expected_hash}" ] || exit_with_error "could not parse expected hash from '${sums_file}'."

   actual_hash="$("${tool}" -- "${iso_file}")"
   actual_hash="${actual_hash%% *}"

   [ "${expected_hash}" = "${actual_hash}" ] || exit_with_error \
      "${tool} MISMATCH for '${iso_file}': expected '${expected_hash}' (per '${sums_file}'), got '${actual_hash}'."

   printf '%s\n' "$0: OK ${tool} '${iso_file}' matches '${sums_file}' (${expected_hash})."
}

verify_one "sha256sum" "${iso_dir}/SHA256SUMS"
verify_one "md5sum" "${iso_dir}/MD5SUMS"
