#!/usr/bin/env bash

# Shared deployment settings for every shipped Film Buddy Mach-O. The host
# toolchain otherwise defaults to the host OS, which can silently make a build
# require a newer macOS than Info.plist advertises.
FILMBUDDY_MACOS_DEPLOYMENT_TARGET="${FILMBUDDY_MACOS_DEPLOYMENT_TARGET:-13.0}"
FILMBUDDY_BUILD_ARCH="${FILMBUDDY_BUILD_ARCH:-arm64}"

if [[ ! "$FILMBUDDY_MACOS_DEPLOYMENT_TARGET" =~ ^[0-9]+(\.[0-9]+){1,2}$ ]]; then
  echo "error: invalid FILMBUDDY_MACOS_DEPLOYMENT_TARGET '$FILMBUDDY_MACOS_DEPLOYMENT_TARGET'" >&2
  return 2 2>/dev/null || exit 2
fi

case "$FILMBUDDY_BUILD_ARCH" in
  arm64|x86_64) ;;
  *)
    echo "error: unsupported FILMBUDDY_BUILD_ARCH '$FILMBUDDY_BUILD_ARCH'" >&2
    return 2 2>/dev/null || exit 2
    ;;
esac

FILMBUDDY_SWIFT_TARGET="${FILMBUDDY_BUILD_ARCH}-apple-macosx${FILMBUDDY_MACOS_DEPLOYMENT_TARGET}"
export FILMBUDDY_MACOS_DEPLOYMENT_TARGET FILMBUDDY_BUILD_ARCH
export MACOSX_DEPLOYMENT_TARGET="$FILMBUDDY_MACOS_DEPLOYMENT_TARGET"

filmbuddy_macos_min_version() {
  local binary="$1"
  xcrun vtool -show-build -arch "$FILMBUDDY_BUILD_ARCH" "$binary" 2>/dev/null | awk '
    /LC_BUILD_VERSION/ { in_build = 1; next }
    in_build && /minos/ { print $2; exit }
    /LC_VERSION_MIN_MACOSX/ { in_legacy = 1; next }
    in_legacy && /version/ { print $2; exit }
  '
}

filmbuddy_version_at_most() {
  local actual="$1"
  local maximum="$2"
  awk -v actual="$actual" -v maximum="$maximum" '
    function component(version, part, values, count) {
      count = split(version, values, ".")
      return part <= count ? values[part] + 0 : 0
    }
    BEGIN {
      for (i = 1; i <= 3; i++) {
        a = component(actual, i)
        m = component(maximum, i)
        if (a < m) exit 0
        if (a > m) exit 1
      }
      exit 0
    }
  '
}

filmbuddy_verify_macos_binary() {
  local binary="$1"
  local maximum="${2:-$FILMBUDDY_MACOS_DEPLOYMENT_TARGET}"
  local min_version

  if ! file "$binary" | grep -q 'Mach-O'; then
    echo "error: expected Mach-O binary at $binary" >&2
    return 1
  fi
  if ! lipo -archs "$binary" | tr ' ' '\n' | grep -qx "$FILMBUDDY_BUILD_ARCH"; then
    echo "error: $binary does not contain required architecture $FILMBUDDY_BUILD_ARCH" >&2
    return 1
  fi
  min_version="$(filmbuddy_macos_min_version "$binary")"
  if [[ -z "$min_version" ]]; then
    echo "error: could not read the macOS deployment target from $binary" >&2
    return 1
  fi
  if ! filmbuddy_version_at_most "$min_version" "$maximum"; then
    echo "error: $binary requires macOS $min_version, above supported macOS $maximum" >&2
    return 1
  fi
}
