#!/bin/bash

# Fail on any error. Display commands being run.
set -ex

if [[ $1 == release ]]; then
  echo "Release build"
else
  echo "Continuous integration build"
fi

bindiff_release=8
binexport_release=12

build_dir=${PWD}/build
bindiff_pkg_root=${PWD}/packaging/dmg/Package
app_dir=${bindiff_pkg_root}/Applications/BinDiff

notarize=$KOKORO_BLAZE_DIR/notarize/blaze-bin/devtools/kokoro/notarizationproxy/client/cmd/notarize

mkdir -p "${build_dir}"

# Verify/extract dependencies
pushd "${KOKORO_GFILE_DIR}"
echo '1f403942ce9f0ba7bfd3f5e0b2f9cae68fcafd4f08cb048b4fb9d75644b030ca  zulu16.30.15-ca-jdk16.0.1-macosx_x64.tar.gz' | \
  shasum -c
# This file is generated by /x20/teams/zynamics/deps/dmg/zulu16.30.19-bindiff_runtime-macosx_aarch64-rebuild.sh
echo '27b02e3223f8b1c8f71fa302e466748e40a589e412b580a9106f8f4dd5a24564  zulu16.30.19-bindiff_runtime-macosx_aarch64.tar.gz' | \
  shasum -c
popd
tar -C "${build_dir}" -xzf "${KOKORO_GFILE_DIR}/zulu16.30.15-ca-jdk16.0.1-macosx_x64.tar.gz"
tar -C "${build_dir}" -xzf "${KOKORO_GFILE_DIR}/zulu16.30.19-bindiff_runtime-macosx_aarch64.tar.gz"

# Copy artifacts
mkdir -p "${build_dir}/jar"
cp "${KOKORO_GFILE_DIR}/bindiff.jar" "${build_dir}/jar/"

# Build standalone application bundle for the Java UI (x86_64)
export JAVA_HOME=${build_dir}/zulu16.30.15-ca-jdk16.0.1-macosx_x64/zulu-16.jdk/Contents/Home
"${JAVA_HOME}/bin/jpackage" \
  --type app-image \
  --app-version "${bindiff_release}" \
  --copyright '(c)2004-2011 zynamics GmbH, (c)2011-2025 Google LLC' \
  --description 'Find similarities and differences in disassembled code' \
  --name BinDiff \
  --dest packaging/dmg/Package/Applications/BinDiff \
  --vendor 'Google LLC' \
  --verbose \
  --add-modules java.base,java.desktop,java.prefs,java.scripting,java.sql,jdk.unsupported,jdk.xml.dom \
  --module-path "${JAVA_HOME}/jmods" \
  --icon packaging/dmg/bindiff-appicon-macos.icns \
  --input "${build_dir}/jar" \
  --main-jar bindiff.jar \
  --mac-package-name BinDiff

# Turn bundle image into a "Universal" one using a small shell script and
# add a separate Java runtime for arm64 (Apple Silicon).
# Rename original native (x86-64) launcher and runtime directory
mv \
  "${app_dir}/BinDiff.app/Contents/MacOS/BinDiff" \
  "${app_dir}/BinDiff.app/Contents/MacOS/BinDiff-x86_64"
mv \
  "${app_dir}/BinDiff.app/Contents/runtime" \
  "${app_dir}/BinDiff.app/Contents/runtime-x86_64"
# Remove app config, this is replaced by arch-specific one below
rm \
  "${app_dir}/BinDiff.app/Contents/app/BinDiff.cfg"
# With the original launcher out of the way, copy the first stage launcher
install -m 0755 \
  "${KOKORO_GFILE_DIR}/bindiff_launcher_macos" \
  "${app_dir}/BinDiff.app/Contents/MacOS/BinDiff"
# Add the AArch64 native launcher and runtime
cp \
  "${build_dir}/MacOS/BinDiff-arm64" \
  "${app_dir}/BinDiff.app/Contents/MacOS/BinDiff-arm64"
mv \
  "${build_dir}/runtime-arm64" \
  "${app_dir}/BinDiff.app/Contents"
# Copy per-arch app config
cp \
  kokoro/dmg/bundle/Contents/app/BinDiff-arm64.cfg \
  kokoro/dmg/bundle/Contents/app/BinDiff-x86_64.cfg \
  "${app_dir}/BinDiff.app/Contents/app"

# Copy latest release artifacts into bundle
mkdir -p \
  "${app_dir}/BinDiff.app/Contents/MacOS/bin" \
  "${app_dir}/Extra/Config" \
  "${app_dir}/Extra/Ghidra" \
  "${app_dir}/Plugins/IDA Pro"
install -m 0755 \
  "${KOKORO_GFILE_DIR}/bindiff" \
  "${KOKORO_GFILE_DIR}/bindiff_config_setup" \
  "${KOKORO_GFILE_DIR}/binexport2dump" \
  "${app_dir}/BinDiff.app/Contents/MacOS/bin/"
cp \
  bindiff_config.proto \
  "${app_dir}/Extra/Config/bindiff_config.proto"
(cd "${app_dir}/Extra/Ghidra/" && \
  unzip -q "${KOKORO_GFILE_DIR}/ghidra_BinExport.zip")
cp \
  "${KOKORO_GFILE_DIR}/bindiff${bindiff_release}_ida.dylib" \
  "${KOKORO_GFILE_DIR}/bindiff${bindiff_release}_ida64.dylib" \
  "${KOKORO_GFILE_DIR}/binexport${binexport_release}_ida.dylib" \
  "${KOKORO_GFILE_DIR}/binexport${binexport_release}_ida64.dylib" \
  "${app_dir}/Plugins/IDA Pro/"
cp \
  bindiff.json \
  "${bindiff_pkg_root}/Library/Application Support/BinDiff/"

if [[ $1 == release ]]; then
  # Release build, code sign and notarize the artifacts
  echo "Code signing bundle artifacts..."

  # Code sign native libraries embedded in the bundle/JAR itself
  mkdir -p jardir
  mv "${app_dir}/BinDiff.app/Contents/app/bindiff.jar" jardir/
  (cd jardir; jar -x -f bindiff.jar; rm bindiff.jar)
  codesign \
    --force \
    --options runtime \
    --timestamp \
    --entitlements packaging/dmg/BinDiff.entitlements \
    --sign "Developer ID Application: Google LLC (EQHXZ8M8AV)" \
    --keychain "${HOME}/Library/Keychains/MacApplicationSigning.keychain" \
    jardir/org/sqlite/native/Mac/aarch64/libsqlitejdbc.dylib \
    jardir/org/sqlite/native/Mac/x86_64/libsqlitejdbc.dylib \
    "${app_dir}/BinDiff.app/Contents/runtime-arm64/Contents/MacOS/libjli.dylib" \
    "${app_dir}/BinDiff.app/Contents/runtime-x86_64/Contents/MacOS/libjli.dylib"
  (cd jardir; jar -c -m META-INF/MANIFEST.MF -f \
    "${app_dir}/BinDiff.app/Contents/app/bindiff.jar" ./*)

  # Sign the application bundle itself
  codesign \
    --force \
    --deep \
    --options runtime \
    --timestamp \
    --entitlements packaging/dmg/BinDiff.entitlements \
    --sign "Developer ID Application: Google LLC (EQHXZ8M8AV)" \
    --keychain "${HOME}/Library/Keychains/MacApplicationSigning.keychain" \
    "${app_dir}/BinDiff.app"

  echo "Notarization..."
  zip -q --symlinks -r \
    "${build_dir}/BinDiff.zip" \
    "${app_dir}/BinDiff.app"
  "${notarize}" \
    --file=${build_dir}/BinDiff.zip

  echo "Stapling..."
  xcrun stapler staple -v "${app_dir}/BinDiff.app"
fi

# Create the installer package
pushd packaging/dmg
pkgbuild \
  --root ./Package \
  --install-location / \
  --component-plist BinDiff.plist \
  --scripts ./Scripts \
  BinDiff.pkg
productbuild \
  --distribution ./Distribution.xml \
  --package-path . \
  --resources ./Resources \
  "${build_dir}/bindiff.pkg"
popd

if [[ $1 == release ]]; then
  mv "${build_dir}/bindiff.pkg" "${build_dir}/bindiff_unsigned.pkg"

  echo "Code signing installer artifacts..."
  productsign \
    --sign "Developer ID Installer" \
    --keychain "${HOME}/Library/Keychains/MacInstallerSigning.keychain" \
    "${build_dir}/bindiff_unsigned.pkg" \
    "${build_dir}/bindiff.pkg"

  echo "Notarization..."
  "${notarize}" \
    --file=${build_dir}/bindiff.pkg

  echo "Stapling..."
  xcrun stapler staple -v "${build_dir}/bindiff.pkg"
fi

# Create the disk image
pushd "${build_dir}"
tar -xzf \
  "${KOKORO_PIPER_DIR}/google3/third_party/zynamics/bindiff/packaging/dmg/bindiff-macos-template.dmg.tar.gz"
mv bindiff-macos-template.dmg bindiff-temp.dmg
mkdir mnt
hdiutil attach bindiff-temp.dmg -readwrite -noautoopen -quiet \
  -mountpoint "${build_dir}/mnt"
cp \
  "bindiff.pkg" \
  "mnt/Install BinDiff.pkg"
cp \
  "${KOKORO_PIPER_DIR}/google3/third_party/zynamics/bindiff/packaging/dmg/bindiff-volicon-macos.icns" \
  "mnt/.VolumeIcon.icns"
SetFile -c icnC "mnt/.VolumeIcon.icns"
SetFile -a C "mnt"
hdiutil detach "${build_dir}/mnt" -quiet -force
hdiutil convert bindiff-temp.dmg -quiet -format UDZO \
  -o "BinDiff${bindiff_release}.dmg"
popd

if [[ $1 == release ]]; then
  echo "Code signing disk image..."
  codesign \
    --force \
    --sign "Developer ID Application: Google LLC (EQHXZ8M8AV)" \
    --keychain "${HOME}/Library/Keychains/MacApplicationSigning.keychain" \
    "${build_dir}/BinDiff${bindiff_release}.dmg"
fi
