#!/usr/bin/env bash
#
# make-app.sh — build a standalone macOS .app from the MiniTerm binary.
#
# Each generated .app has its OWN bundle id, so macOS treats it as a separate
# application: separate Dock icon, separate ⌘-Tab entry. Run this script once
# per app you want.
#
# Usage:
#   ./make-app.sh \
#       --name "Claude · Projekt A" \
#       --bundle-id com.yourname.claude.projekta \
#       --workdir ~/code/project-a \
#       --command "claude" \
#       [--font-size 13] \
#       [--font "JetBrains Mono"] \
#       [--icon ./icons/projekta.png] \   # .png/.jpg (auto-converted) or .icns
#       [--out ~/Applications]
#
# Build the binary fresh? The script runs `swift build -c release` automatically
# the first time and reuses the result for further apps.

set -euo pipefail

# ---- defaults -------------------------------------------------------------
NAME=""
BUNDLE_ID=""
WORKDIR=""
COMMAND=""
FONT_SIZE="13"
FONT_NAME="Menlo"
ICON=""
OUTDIR="$HOME/Applications"

# ---- parse args -----------------------------------------------------------
while [[ $# -gt 0 ]]; do
  case "$1" in
    --name)       NAME="$2"; shift 2 ;;
    --bundle-id)  BUNDLE_ID="$2"; shift 2 ;;
    --workdir)    WORKDIR="$2"; shift 2 ;;
    --command)    COMMAND="$2"; shift 2 ;;
    --font-size)  FONT_SIZE="$2"; shift 2 ;;
    --font)       FONT_NAME="$2"; shift 2 ;;
    --icon)       ICON="$2"; shift 2 ;;
    --out)        OUTDIR="$2"; shift 2 ;;
    -h|--help)
      grep '^#' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) echo "Unknown option: $1" >&2; exit 1 ;;
  esac
done

if [[ -z "$NAME" || -z "$BUNDLE_ID" ]]; then
  echo "Error: --name and --bundle-id are required." >&2
  echo "Run './make-app.sh --help' for usage." >&2
  exit 1
fi

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

# ---- build binary once ----------------------------------------------------
BIN=".build/release/MiniTerm"
if [[ ! -f "$BIN" ]]; then
  echo "==> Building MiniTerm (release)…"
  swift build -c release
fi

# Keep workdir portable across machines/users: store paths under the current
# home directory as a literal "~", so each app expands it per-user at runtime
# (Swift's expandingTildeInPath). Note the shell may have already expanded a "~"
# you typed on the command line into an absolute $HOME path, so we normalize that
# back to "~" too. Paths outside $HOME stay absolute (genuinely machine-specific).
case "$WORKDIR" in
  "$HOME")   WORKDIR="~" ;;
  "$HOME"/*) WORKDIR="~/${WORKDIR#"$HOME"/}" ;;
esac

# ---- assemble the .app bundle ---------------------------------------------
APP="$OUTDIR/$NAME.app"
echo "==> Creating $APP"
rm -rf "$APP"
mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"

cp "$BIN" "$APP/Contents/MacOS/MiniTerm"
chmod +x "$APP/Contents/MacOS/MiniTerm"

# Build an .icns from a square source image (PNG/JPG/…) using macOS tools.
make_icns_from_image() {
  local src="$1" dest="$2"
  local iconset
  iconset="$(mktemp -d)/icon.iconset"
  mkdir -p "$iconset"
  # All sizes Apple expects in an .iconset
  local sizes=(16 32 128 256 512)
  for s in "${sizes[@]}"; do
    sips -z "$s" "$s"             "$src" --out "$iconset/icon_${s}x${s}.png"    >/dev/null
    sips -z "$((s*2))" "$((s*2))" "$src" --out "$iconset/icon_${s}x${s}@2x.png" >/dev/null
  done
  iconutil -c icns "$iconset" -o "$dest"
  rm -rf "$(dirname "$iconset")"
}

ICON_KEY=""
if [[ -n "$ICON" ]]; then
  if [[ ! -f "$ICON" ]]; then
    echo "   (warning: --icon file not found: $ICON; skipping icon)" >&2
  elif [[ "$ICON" == *.icns ]]; then
    cp "$ICON" "$APP/Contents/Resources/AppIcon.icns"
    ICON_KEY="<key>CFBundleIconFile</key><string>AppIcon</string>"
  elif command -v sips >/dev/null 2>&1 && command -v iconutil >/dev/null 2>&1; then
    echo "==> Converting $ICON to .icns…"
    if make_icns_from_image "$ICON" "$APP/Contents/Resources/AppIcon.icns"; then
      ICON_KEY="<key>CFBundleIconFile</key><string>AppIcon</string>"
    else
      echo "   (warning: icon conversion failed; building without icon)" >&2
    fi
  else
    echo "   (warning: sips/iconutil not available; pass a .icns file instead)" >&2
  fi
fi

cat > "$APP/Contents/Info.plist" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleName</key><string>${NAME}</string>
    <key>CFBundleDisplayName</key><string>${NAME}</string>
    <key>CFBundleExecutable</key><string>MiniTerm</string>
    <key>CFBundleIdentifier</key><string>${BUNDLE_ID}</string>
    <key>CFBundlePackageType</key><string>APPL</string>
    <key>CFBundleVersion</key><string>1</string>
    <key>CFBundleShortVersionString</key><string>1.0</string>
    <key>LSMinimumSystemVersion</key><string>13.0</string>
    <key>NSHighResolutionCapable</key><true/>
    ${ICON_KEY}
    <key>MTCommand</key><string>${COMMAND}</string>
    <key>MTWorkingDirectory</key><string>${WORKDIR}</string>
    <key>MTWindowTitle</key><string>${NAME}</string>
    <key>MTFontSize</key><integer>${FONT_SIZE}</integer>
    <key>MTFontName</key><string>${FONT_NAME}</string>
</dict>
</plist>
PLIST

# ---- ad-hoc codesign (helps on Apple Silicon / Gatekeeper) ----------------
if command -v codesign >/dev/null 2>&1; then
  codesign --force --deep --sign - "$APP" >/dev/null 2>&1 \
    && echo "==> Ad-hoc signed." \
    || echo "   (codesign skipped/failed — app still runs)"
fi

echo "==> Done: $APP"
echo "    Command : ${COMMAND:-<plain shell>}"
echo "    Workdir : ${WORKDIR:-<home>}"
echo "    Font    : ${FONT_NAME} ${FONT_SIZE}pt"
