#!/bin/bash

MACOS_SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
LIGHT="${LIGHT:=0}"
if [ "${CLIENT_ONLY}" == "1" ]; then
  LIGHT="1"
fi
if [ "${LIGHT}" == "1" ]; then
  APP_NAME="Xpra-Light"
else
  APP_NAME="Xpra"
fi
APP_DIR="${MACOS_SCRIPT_DIR}/image/${APP_NAME}.app"
CONTENTS_DIR="${APP_DIR}/Contents"
X11_DIR="${CONTENTS_DIR}/Frameworks/X11"

get_team_id() {
  local keyname="$1"
  # Ad-hoc always has no Team ID
  if [[ "$keyname" == "-" ]]; then
    return
  fi
  # Query the certificate
  security find-identity -v -p codesigning | grep "$keyname" | head -1 | grep -o '([A-Z0-9]\{10\})' | tr -d '()'
}

export CODESIGN_KEYNAME="${CODESIGN_KEYNAME:=-}"
# verify that it is unlocked:
if [ -z "${KEYCHAIN}" ]; then
  KEYCHAIN="$HOME/Library/Keychains/login.keychain-db"
  echo "using default login keychain ${KEYCHAIN}"
fi
if ! security show-keychain-info "$KEYCHAIN" 2>/dev/null; then
    echo "Keychain is locked, cannot sign!"
    exit 1
fi

TEAM_ID=$(get_team_id "$CODESIGN_KEYNAME")
if [ -z "$TEAM_ID" ]; then
  ENTITLEMENTS_FILE="${MACOS_SCRIPT_DIR}/entitlements.plist"
else
  ENTITLEMENTS_FILE=""
fi
export ENTITLEMENTS_FILE

# for libraries and executables:
function sign_runtime() {
  codesign --remove-signature "$@" 2>/dev/null || true
  if [ -z "${ENTITLEMENTS_FILE}" ]; then
    codesign --sign "${CODESIGN_KEYNAME}" --options runtime --timestamp "$@"
  else
    codesign --sign "${CODESIGN_KEYNAME}" --options runtime --timestamp --entitlements "${ENTITLEMENTS_FILE}" "$@"
  fi
}

# for plain python modules:
function sign() {
  codesign --remove-signature "$@" 2>/dev/null || true
  codesign --sign "${CODESIGN_KEYNAME}" "$@"
}

export -f sign
export -f sign_runtime

echo "*******************************************************************************"
echo "Signing"
echo "  so"
find "${CONTENTS_DIR}/" -type f -name "*.so" -exec bash -c 'sign_runtime "$0"' {} \;
echo "  dylibs"
find "${CONTENTS_DIR}/" -type f -name "*.dylib" -exec bash -c 'sign_runtime "$0"' {} \;
echo "  pyc"
find "${CONTENTS_DIR}/" -type f -name "*.pyc" -exec bash -c 'sign "$0"' {} \;

if [ -d "${X11_DIR}/bin" ]; then
    echo "  X11"
    # Skip symlinks: when both libFoo.dylib (symlink) and libFoo.N.dylib (target)
    # are passed in the same codesign batch, codesign signs the target via the
    # symlink first and then errors "is already signed" on the explicit target.
    for f in "${X11_DIR}/bin/"* "${X11_DIR}/lib/"*.dylib "${X11_DIR}/lib/dri/"*; do
      [[ -L "${f}" ]] && continue
      [[ -e "${f}" ]] || continue
      sign_runtime "${f}"
    done
fi
echo "  Frameworks/bin"
# only sign the actual binaries / unique scripts, not the symlinks:
for bin in Python daemonizer gst-inspect-1.0 gst-launch-1.0 gst-plugin-scanner sshpass xpra_signal_listener; do
  sign_runtime "${CONTENTS_DIR}/Frameworks/bin/${bin}"
done
echo "  Helpers"
sign_runtime "${CONTENTS_DIR}/Helpers/"*
echo "  Xpra_NoDock.app"
sign_runtime "${CONTENTS_DIR}/Xpra_NoDock.app"
echo "  MacOS/Xpra"
sign_runtime "${CONTENTS_DIR}/MacOS/Xpra"
echo "  ${APP_NAME}"
sign_runtime "${APP_DIR}"

echo "Verification"
echo "  extended attributes (should be empty)"
xattr -l "${APP_DIR}"
# Verify just the bundle seal, then deep verification (checks all components)
echo "  signature"
codesign --verify --verbose=1 "${APP_DIR}" && codesign --verify --deep --strict --verbose=1 "${APP_DIR}"
echo "  gatekeeper"
spctl --status
spctl --assess -vvv --type execute "${APP_DIR}"

echo "*******************************************************************************"
echo "Copying ${APP_NAME} to ~/Desktop"
ditto "${APP_DIR}" "${HOME}/Desktop/${APP_NAME}.app"
