#!/usr/bin/env bash
set -euo pipefail

usage() {
  cat >&2 <<'EOF'
usage: rebuild_from_source_package.sh CORRESPONDING_SOURCE_TAR_XZ OUTPUT_DIRECTORY

Rebuilds MobileVLCKit 3.7.3-beam.2 from BEAM's exact corresponding-source
package with network access disabled. OUTPUT_DIRECTORY must not already exist.
EOF
}

fail() {
  printf 'BLOCKED: %s\n' "$*" >&2
  exit 1
}

if (( $# != 2 )); then
  usage
  exit 64
fi

source_archive=$1
requested_output=$2
expected_source_sha256=df35d4b7e8d926c05e77a488c3a8182e456cb832deed3cf34dc657ffb52c9208
expected_version=3.7.3-beam.2

[[ -f "$source_archive" && ! -L "$source_archive" && -s "$source_archive" ]] ||
  fail "source package must be a non-empty regular file: $source_archive"
[[ ! -e "$requested_output" && ! -L "$requested_output" ]] ||
  fail "output already exists: $requested_output"

for command in awk cp find git lipo mkdir mktemp mv otool python3 shasum tar xcodebuild xcrun; do
  command -v "$command" >/dev/null || fail "required command is unavailable: $command"
done

actual_source_sha256=$(shasum -a 256 "$source_archive" | awk '{print $1}')
[[ "$actual_source_sha256" == "$expected_source_sha256" ]] ||
  fail "source package SHA-256 is $actual_source_sha256; expected $expected_source_sha256"

xcode_major=$(xcodebuild -version | awk '/Xcode / { split($2, value, "."); print value[1] }')
[[ "$xcode_major" =~ ^[0-9]+$ && "$xcode_major" -ge 26 ]] ||
  fail "Xcode 26 or newer is required"

source_archive=$(cd "$(dirname "$source_archive")" && pwd)/$(basename "$source_archive")
output_parent=$(dirname "$requested_output")
mkdir -p "$output_parent"
output_parent=$(cd "$output_parent" && pwd)
output_path="$output_parent/$(basename "$requested_output")"
[[ ! -e "$output_path" && ! -L "$output_path" ]] ||
  fail "output already exists: $output_path"

work_root=$(mktemp -d "${TMPDIR:-/tmp}/beam-vlckit-rebuild.XXXXXX") ||
  fail "could not create the rebuild workspace"
install_root=$(mktemp -d "$output_parent/.beam-vlckit-rebuild.XXXXXX") || {
  rm -rf "$work_root"
  fail "could not create the atomic output workspace"
}
installed=false
cleanup() {
  if [[ -n "${work_root:-}" && -d "$work_root" ]]; then
    rm -rf "$work_root"
  fi
  if [[ "$installed" != true && -n "${install_root:-}" && -d "$install_root" ]]; then
    rm -rf "$install_root"
  fi
}
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM

tar -xJf "$source_archive" -C "$work_root"
vlckit_root="$work_root/source/VLCKit"
vlc_root="$vlckit_root/libvlc/vlc"
tool_root="$work_root/beam-tool"
audit_root="$work_root/rebuild-audit"

for required in \
  "$vlckit_root/buildMobileVLCKit.sh" \
  "$vlc_root/extras/tools" \
  "$tool_root/audit_link_inputs.py" \
  "$tool_root/audit_static_modules.py" \
  "$tool_root/audit_xcframework.py" \
  "$tool_root/baseline-modules.txt" \
  "$tool_root/pins.env" \
  "$work_root/SOURCE-MANIFEST.txt" \
  "$work_root/audit/source-inputs-sha512.tsv"; do
  [[ -e "$required" && ! -L "$required" ]] || fail "source package is incomplete: $required"
done

mkdir -p "$vlc_root/contrib/tarballs"
while IFS= read -r -d '' download; do
  cp -p "$download" "$vlc_root/contrib/tarballs/$(basename "$download")"
done < <(find "$work_root/source-downloads/contrib/tarballs" -type f -print0)
while IFS= read -r -d '' download; do
  cp -p "$download" "$vlc_root/extras/tools/$(basename "$download")"
done < <(find "$work_root/source-downloads/extras/tools" -type f -print0)

source_date_epoch=$(awk -F= '$1 == "source_date_epoch" { count += 1; value = $2 } END { if (count != 1) exit 1; print value }' "$work_root/SOURCE-MANIFEST.txt") ||
  fail "source_date_epoch is missing or duplicated"
[[ "$source_date_epoch" =~ ^[1-9][0-9]*$ ]] || fail "source_date_epoch is malformed"

mkdir -p "$audit_root/modules/ios/iPhone" "$audit_root/link-inputs/ios"
export LC_ALL=C
export SOURCE_DATE_EPOCH="$source_date_epoch"
export ZERO_AR_DATE=1
export BEAM_VLCKIT_IOS_DEPLOYMENT_TARGET=15.0
export BEAM_VLCKIT_MODULE_FILTER="$tool_root/audit_static_modules.py"
export BEAM_VLCKIT_LICENSE_AUDIT_ROOT="$audit_root/modules/ios"
export BEAM_VLCKIT_PINS="$tool_root/pins.env"
export BEAM_VLCKIT_BASELINE="$tool_root/baseline-modules.txt"
export BEAM_VLCKIT_FORBIDDEN_PREFIX="$work_root/forbidden-proprietary-app-input"

(
  cd "$vlckit_root"
  ./buildMobileVLCKit.sh -n -f -v
)

framework="$vlckit_root/build/MobileVLCKit.xcframework"
[[ -d "$framework" && ! -L "$framework" ]] || fail "rebuild did not produce MobileVLCKit.xcframework"

python3 "$tool_root/audit_link_inputs.py" \
  --vlc-root "$vlc_root" \
  --os-style iPhone \
  --minimum-os 15.0 \
  --audit-dir "$audit_root/link-inputs/ios" \
  --forbidden-prefix "$BEAM_VLCKIT_FORBIDDEN_PREFIX"
python3 "$tool_root/audit_xcframework.py" \
  --xcframework "$framework" \
  --product MobileVLCKit \
  --platform ios \
  --minimum-os 15.0 \
  --approved-inventory "$audit_root/modules/ios/iPhone/approved-module-entries.tsv" \
  --forbidden-prefix "$BEAM_VLCKIT_FORBIDDEN_PREFIX" \
  --report "$audit_root/ios-xcframework.json"

cp -R "$framework" "$install_root/MobileVLCKit.xcframework"
cp -R "$audit_root" "$install_root/audit"
cp "$work_root/SOURCE-MANIFEST.txt" "$install_root/SOURCE-MANIFEST.txt"
cp "$work_root/audit/source-inputs-sha512.tsv" "$install_root/source-inputs-sha512.tsv"
{
  printf 'version=%s\n' "$expected_version"
  printf 'corresponding_source_sha256=%s\n' "$actual_source_sha256"
  printf 'xcode=%s\n' "$(xcodebuild -version | tr '\n' ' ')"
  printf 'sdk=%s\n' "$(xcrun --sdk iphoneos --show-sdk-version)"
} > "$install_root/REBUILD-MANIFEST.txt"
(
  cd "$install_root"
  find . -type f ! -name SHA256SUMS -print0 | LC_ALL=C sort -z | xargs -0 shasum -a 256
) > "$install_root/SHA256SUMS"

mv "$install_root" "$output_path"
installed=true
printf 'Rebuilt and audited MobileVLCKit at %s\n' "$output_path"
