#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LABEL="com.docreader.tray"
PLIST_DIR="$HOME/Library/LaunchAgents"
PLIST_PATH="$PLIST_DIR/$LABEL.plist"
LOG_DIR="$HOME/Library/Logs"
APP_DIR="$HOME/.doc-reader-managed"
RUNNER="$APP_DIR/run-doc-reader"
VENV_DIR="$APP_DIR/.venv"
READ_DOCS_HELPER="$APP_DIR/read-docs"
NATIVE_APP="$APP_DIR/Doc Reader.app"
NATIVE_EXECUTABLE="$NATIVE_APP/Contents/MacOS/DocReader"
APPLICATIONS_DIR="$HOME/Applications"
APPLICATIONS_APP="$APPLICATIONS_DIR/Doc Reader.app"
APPLICATIONS_EXECUTABLE="$APPLICATIONS_APP/Contents/MacOS/DocReader"
PROGRAM="$RUNNER"
PREPARE_MANAGED_ONLY=0

if [[ "${1:-}" == "--prepare-managed-only" ]]; then
  PREPARE_MANAGED_ONLY=1
fi

if [[ ! -x "$SCRIPT_DIR/run-doc-reader" ]]; then
  echo "[doc-reader] $SCRIPT_DIR/run-doc-reader is missing or not executable." >&2
  exit 1
fi
if [[ ! -x "$SCRIPT_DIR/read-selection-service.sh" ]]; then
  echo "[doc-reader] $SCRIPT_DIR/read-selection-service.sh is missing or not executable." >&2
  exit 1
fi
if [[ ! -x "$SCRIPT_DIR/build-macos-app" ]]; then
  echo "[doc-reader] $SCRIPT_DIR/build-macos-app is missing or not executable." >&2
  exit 1
fi
NODE_BIN="${NODE_BIN:-$(command -v node || true)}"
if [[ -z "$NODE_BIN" ]]; then
  echo "[doc-reader] node is required for startup orchestration." >&2
  exit 1
fi

# Install a managed app copy outside the npm package so launchd owns runtime lifecycle.
mkdir -p "$APP_DIR"
cp "$SCRIPT_DIR/run-doc-reader" "$APP_DIR/run-doc-reader"
chmod +x "$APP_DIR/run-doc-reader"
cat > "$READ_DOCS_HELPER" <<EOF
#!/usr/bin/env bash
set -euo pipefail
export DOC_READER_VENV_DIR="\${DOC_READER_VENV_DIR:-$VENV_DIR}"
export DOC_READER_MANAGED_ROOT="\${DOC_READER_MANAGED_ROOT:-$APP_DIR}"
exec "$NODE_BIN" "$SCRIPT_DIR/bin/read-docs.js" "\$@"
EOF
chmod +x "$READ_DOCS_HELPER"
cp "$SCRIPT_DIR/read-selection-service.sh" "$APP_DIR/read-selection-service.sh"
chmod +x "$APP_DIR/read-selection-service.sh"
cp "$SCRIPT_DIR/requirements.txt" "$APP_DIR/requirements.txt"
rm -rf "$APP_DIR/doc_reader"
cp -R "$SCRIPT_DIR/doc_reader" "$APP_DIR/doc_reader"

if [[ "$PREPARE_MANAGED_ONLY" == "1" ]]; then
  DOC_READER_VENV_DIR="$VENV_DIR" "$RUNNER" --prepare-only
  echo "[doc-reader] Managed runtime ready: $APP_DIR"
  if [[ -e "$APPLICATIONS_APP" ]]; then
    echo "[doc-reader] Applications app: $APPLICATIONS_APP"
  fi
  exit 0
fi

"$SCRIPT_DIR/build-macos-app" "$APP_DIR"
mkdir -p "$APPLICATIONS_DIR"
if [[ -L "$APPLICATIONS_APP" ]]; then
  rm "$APPLICATIONS_APP"
fi
if [[ -d "$APPLICATIONS_APP" ]]; then
  EXISTING_BUNDLE_ID="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$APPLICATIONS_APP/Contents/Info.plist" 2>/dev/null || true)"
  if [[ "$EXISTING_BUNDLE_ID" != "com.sproutseeds.read-docs" ]]; then
    echo "[doc-reader] Applications app already exists and is not Doc Reader: $APPLICATIONS_APP" >&2
    exit 1
  fi
  rm -rf "$APPLICATIONS_APP"
elif [[ -e "$APPLICATIONS_APP" ]]; then
  echo "[doc-reader] Applications app path already exists and is not an app bundle: $APPLICATIONS_APP" >&2
  exit 1
fi
cp -R "$NATIVE_APP" "$APPLICATIONS_APP"
if [[ -x "$APPLICATIONS_EXECUTABLE" ]]; then
  PROGRAM="$APPLICATIONS_EXECUTABLE"
elif [[ -x "$NATIVE_EXECUTABLE" ]]; then
  PROGRAM="$NATIVE_EXECUTABLE"
fi
if [[ -x /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister ]]; then
  /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "$APPLICATIONS_APP" >/dev/null 2>&1 || true
fi

# Ensure env/deps are ready before launchctl starts it.
DOC_READER_VENV_DIR="$VENV_DIR" "$RUNNER" --prepare-only

mkdir -p "$PLIST_DIR" "$LOG_DIR"

cat > "$PLIST_PATH" <<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>Label</key>
    <string>$LABEL</string>

    <key>ProgramArguments</key>
    <array>
      <string>$PROGRAM</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <false/>

    <key>ProcessType</key>
    <string>Interactive</string>

    <key>StandardOutPath</key>
    <string>$LOG_DIR/doc-reader-tray.log</string>

    <key>StandardErrorPath</key>
    <string>$LOG_DIR/doc-reader-tray.err.log</string>

    <key>WorkingDirectory</key>
    <string>$APP_DIR</string>

    <key>EnvironmentVariables</key>
    <dict>
      <key>DOC_READER_VENV_DIR</key>
      <string>$VENV_DIR</string>
      <key>DOC_READER_DISABLE_WEB_FALLBACK</key>
      <string>1</string>
    </dict>
  </dict>
</plist>
PLIST

if launchctl print "gui/$UID/$LABEL" >/dev/null 2>&1; then
  launchctl bootout "gui/$UID/$LABEL" >/dev/null 2>&1 || true
fi
launchctl bootout "gui/$UID" "$PLIST_PATH" >/dev/null 2>&1 || true
BOOTSTRAPPED=0
for _attempt in 1 2 3; do
  if launchctl bootstrap "gui/$UID" "$PLIST_PATH"; then
    BOOTSTRAPPED=1
    break
  fi
  sleep 1
done
if [[ "$BOOTSTRAPPED" != "1" ]]; then
  echo "[doc-reader] Could not bootstrap LaunchAgent: $PLIST_PATH" >&2
  exit 1
fi
launchctl enable "gui/$UID/$LABEL"
launchctl kickstart -k "gui/$UID/$LABEL"

echo "[doc-reader] App agent installed and started."
echo "[doc-reader] LaunchAgent: $PLIST_PATH"
echo "[doc-reader] Managed install: $APP_DIR"
echo "[doc-reader] Native app: $NATIVE_APP"
echo "[doc-reader] Applications app: $APPLICATIONS_APP"
echo "[doc-reader] It will start at login and can be controlled with read-docs start/stop/status."
