#!/usr/bin/env bash

set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PROJECT_DIR="$ROOT_DIR/CommandNotch"
PROJECT_SPEC="$PROJECT_DIR/project.yml"
XCODEPROJ="$PROJECT_DIR/CommandNotch.xcodeproj"
SCHEME="Release-CommandNotch"
CONFIGURATION="Release"
APP_NAME="CommandNotch"
DERIVED_DATA_DIR="$ROOT_DIR/build/release"
DIST_DIR="$ROOT_DIR/dist"
STAGING_DIR="$DIST_DIR/dmg"
APP_BUNDLE="$DERIVED_DATA_DIR/Build/Products/$CONFIGURATION/$APP_NAME.app"
DMG_PATH="$DIST_DIR/$APP_NAME.dmg"

usage() {
  cat <<EOF
Usage: $(basename "$0") [--skip-generate]

Builds $APP_NAME.app and packages it into a drag-to-Applications DMG.

Options:
  --skip-generate   Reuse the existing Xcode project without running xcodegen.
  -h, --help        Show this help text.
EOF
}

require_command() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "error: required command not found: $1" >&2
    exit 1
  fi
}

configure_developer_dir() {
  local current_dir
  current_dir="$(xcode-select -p 2>/dev/null || true)"

  if [[ "$current_dir" == "/Library/Developer/CommandLineTools" ]]; then
    local xcode_dir="/Applications/Xcode.app/Contents/Developer"
    if [[ -d "$xcode_dir" ]]; then
      export DEVELOPER_DIR="$xcode_dir"
      echo "Using Xcode developer directory: $DEVELOPER_DIR"
      return
    fi

    echo "error: xcode-select is pointing at Command Line Tools, and /Applications/Xcode.app was not found." >&2
    echo "Install Xcode or run: sudo xcode-select -s /Applications/Xcode.app/Contents/Developer" >&2
    exit 1
  fi
}

skip_generate=0

while (($# > 0)); do
  case "$1" in
    --skip-generate)
      skip_generate=1
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "error: unknown argument: $1" >&2
      usage >&2
      exit 1
      ;;
  esac
done

require_command xcodebuild
require_command hdiutil
if [[ $skip_generate -eq 0 ]]; then
  require_command xcodegen
fi

configure_developer_dir

if [[ ! -f "$PROJECT_SPEC" ]]; then
  echo "error: project spec not found at $PROJECT_SPEC" >&2
  exit 1
fi

if [[ $skip_generate -eq 0 ]]; then
  echo "Generating Xcode project..."
  xcodegen generate --spec "$PROJECT_SPEC"
fi

if [[ ! -d "$XCODEPROJ" ]]; then
  echo "error: Xcode project not found at $XCODEPROJ" >&2
  exit 1
fi

echo "Building $APP_NAME.app..."
rm -rf "$DERIVED_DATA_DIR"
xcodebuild \
  -project "$XCODEPROJ" \
  -scheme "$SCHEME" \
  -configuration "$CONFIGURATION" \
  -derivedDataPath "$DERIVED_DATA_DIR" \
  build

if [[ ! -d "$APP_BUNDLE" ]]; then
  echo "error: built app bundle not found at $APP_BUNDLE" >&2
  exit 1
fi

echo "Preparing DMG staging folder..."
rm -rf "$STAGING_DIR" "$DMG_PATH"
mkdir -p "$STAGING_DIR"
ditto "$APP_BUNDLE" "$STAGING_DIR/$APP_NAME.app"
ln -s /Applications "$STAGING_DIR/Applications"

echo "Creating DMG..."
hdiutil create \
  -volname "$APP_NAME" \
  -srcfolder "$STAGING_DIR" \
  -ov \
  -format UDZO \
  "$DMG_PATH"

echo
echo "Done:"
echo "  App: $APP_BUNDLE"
echo "  DMG: $DMG_PATH"
