#!/usr/bin/env bash
#
# mac_package.sh - turn a freshly built bnc.app into something that runs on
#                  another Mac without requiring a paid Apple Developer ID.
#
# Purpose: qmake/make on macOS produces src/../bnc.app (a plain Qt app
#          bundle, unsigned, with no bundled Qt frameworks). This script
#          - bundles the required Qt frameworks/plugins via macdeployqt
#          - ad-hoc code-signs the whole bundle (no Apple account needed;
#            required on Apple Silicon just to let the binary launch)
#          - optionally signs with a real "Developer ID Application"
#            identity if CODESIGN_IDENTITY is set in the environment
#          - packages the result as a dmg (drag-to-Applications, the
#            expected format for external users) and/or a zip
#
# Usage:   packaging/mac_package.sh [--format dmg|zip|both] [path/to/bnc.app]
#          CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
#            packaging/mac_package.sh
#
# Note:    Without a real Developer ID + notarization, macOS Gatekeeper will
#          still show an "unidentified developer" warning the first time a
#          downloaded copy is opened. Tell recipients to right-click (or
#          Control-click) the app and choose "Open" once, or run
#          `xattr -cr bnc.app` after unpacking, to bypass it. No signature
#          purchase is required for local use or for users willing to do
#          that one-time step.

set -euo pipefail

if [[ "$(uname -s)" != "Darwin" ]]; then
  echo "error: this script must be run on macOS" >&2
  exit 1
fi

FORMAT="dmg"
APP_PATH=""
while [[ $# -gt 0 ]]; do
  case "$1" in
    --format)
      FORMAT="$2"
      shift 2
      ;;
    *)
      APP_PATH="$1"
      shift
      ;;
  esac
done
case "$FORMAT" in
  dmg|zip|both) ;;
  *) echo "error: --format must be dmg, zip, or both (got '$FORMAT')" >&2; exit 1 ;;
esac

APP_PATH="${APP_PATH:-bnc.app}"
if [[ ! -d "$APP_PATH" ]]; then
  # fall back to the usual qmake output location (src.pro: TARGET = ../bnc)
  if [[ -d "$(dirname "$0")/../bnc.app" ]]; then
    APP_PATH="$(dirname "$0")/../bnc.app"
  else
    echo "error: could not find bnc.app (looked for '$APP_PATH')" >&2
    echo "       build it first (qmake && make), then pass its path explicitly" >&2
    exit 1
  fi
fi
APP_PATH="$(cd "$(dirname "$APP_PATH")" && pwd)/$(basename "$APP_PATH")"
APP_NAME="$(basename "$APP_PATH" .app)"

command -v macdeployqt >/dev/null 2>&1 || {
  echo "error: macdeployqt not found on PATH (it ships with Qt, e.g. <QtDir>/bin)" >&2
  exit 1
}

echo "== bundling Qt frameworks/plugins into $APP_PATH =="
macdeployqt "$APP_PATH"

if [[ -n "${CODESIGN_IDENTITY:-}" ]]; then
  echo "== signing with identity: $CODESIGN_IDENTITY =="
  codesign --force --deep --options runtime --sign "$CODESIGN_IDENTITY" "$APP_PATH"
  echo "   (remember to notarize + staple for Gatekeeper-clean distribution:"
  echo "    xcrun notarytool submit <dmg-or-zip> --keychain-profile <profile> --wait"
  echo "    xcrun stapler staple \"$APP_PATH\")"
else
  echo "== ad-hoc signing (no Apple account required) =="
  codesign --force --deep --sign - "$APP_PATH"
fi

echo "== verifying signature =="
codesign --verify --deep --strict --verbose=2 "$APP_PATH"

if [[ "$FORMAT" == "zip" || "$FORMAT" == "both" ]]; then
  ZIP_PATH="${APP_PATH%.app}.zip"
  echo "== packaging $ZIP_PATH =="
  rm -f "$ZIP_PATH"
  # ditto preserves the code signature; plain zip/tar can corrupt it
  ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
  echo "Done: $ZIP_PATH"
fi

if [[ "$FORMAT" == "dmg" || "$FORMAT" == "both" ]]; then
  DMG_PATH="${APP_PATH%.app}.dmg"
  echo "== packaging $DMG_PATH =="
  rm -f "$DMG_PATH"
  STAGING_DIR="$(mktemp -d)"
  trap 'rm -rf "$STAGING_DIR"' EXIT
  ditto "$APP_PATH" "$STAGING_DIR/$APP_NAME.app"
  ln -s /Applications "$STAGING_DIR/Applications"
  hdiutil create -volname "$APP_NAME" -srcfolder "$STAGING_DIR" -ov -format UDZO "$DMG_PATH"
  echo "Done: $DMG_PATH"
fi

echo
echo "Recipients of an unsigned/ad-hoc build must bypass Gatekeeper once:"
echo "  - right-click the app -> Open -> confirm, or"
echo "  - run: xattr -cr \"$APP_NAME.app\"  after mounting/unzipping"
