#!/bin/bash
set -euo pipefail
CORE_COMMAND_FILE="${BASH_SOURCE[0]}"
while [ -L "$CORE_COMMAND_FILE" ]; do
  CORE_LINK="$(readlink "$CORE_COMMAND_FILE")"
  case "$CORE_LINK" in /*) CORE_COMMAND_FILE="$CORE_LINK" ;; *) CORE_COMMAND_FILE="$(dirname "$CORE_COMMAND_FILE")/$CORE_LINK" ;; esac
done
CORE_PACKAGE_ROOT="$(cd "$(dirname "$CORE_COMMAND_FILE")" && pwd)"
export BIZCLAW_CORE_HOME="${BIZCLAW_CORE_HOME:-$HOME/.bizclaw-core}"
export CORE_PYTHON="$CORE_PACKAGE_ROOT/runtime/python/bin/python3"
export PYTHONHOME="$CORE_PACKAGE_ROOT/runtime/python"
unset PYTHONPATH
export CORE_OFFICE_SCRIPT="$CORE_PACKAGE_ROOT/scripts/office/office.py"
if [ "$(uname -s)" = Darwin ]; then
  export CORE_SOFFICE="$CORE_PACKAGE_ROOT/runtime/LibreOffice.app/Contents/MacOS/soffice"
  export CORE_TESSERACT="$CORE_PACKAGE_ROOT/runtime/ocr/tesseract"
  export TESSDATA_PREFIX="$CORE_PACKAGE_ROOT/runtime/tessdata"
else
  export CORE_SOFFICE="${CORE_SOFFICE:-/usr/bin/soffice}"
  export CORE_TESSERACT="${CORE_TESSERACT:-/usr/bin/tesseract}"
  if [ -d /usr/share/tesseract-ocr/5/tessdata ]; then export TESSDATA_PREFIX=/usr/share/tesseract-ocr/5/tessdata; fi
  export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
  export DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS:-unix:path=$XDG_RUNTIME_DIR/bus}"
fi
export CORE_OCR_LANG="${CORE_OCR_LANG:-chi_tra+eng}"
export PLAYWRIGHT_BROWSERS_PATH="$CORE_PACKAGE_ROOT/runtime/browsers"
export BIZCLAW_LICENSE_HUB_URL="${BIZCLAW_LICENSE_HUB_URL:-https://bizclaw.com}"
export PATH="$CORE_PACKAGE_ROOT/bin:$PATH"
export BIZCLAW_PACKAGE_ROOT="$CORE_PACKAGE_ROOT"
if [ "${1:-help}" != service ]; then
  if [ "${1:-help}" != help ] && [ "${1:-}" != --help ]; then exec "$CORE_PACKAGE_ROOT/bin/bun" "$CORE_PACKAGE_ROOT/src/cli.ts" "$@"; fi
  "$CORE_PACKAGE_ROOT/bin/bun" "$CORE_PACKAGE_ROOT/src/cli.ts" "$@"
  if [ "${1:-help}" = help ] || [ "${1:-}" = --help ]; then
    printf '\nBackground service: bizclaw-core service start|stop|restart|status|remove\n'
  fi
  exit 0
fi
shift
CORE_SERVICE_ACTION="${1:-status}"
CORE_SERVICE_LABEL="${BIZCLAW_SERVICE_LABEL:-ai.bizclaw.core.cli}"
case "$CORE_SERVICE_LABEL" in ai.bizclaw.core.cli*) ;; *) echo 'Invalid Core service label' >&2; exit 2 ;; esac
[[ "$CORE_SERVICE_LABEL" =~ ^[a-zA-Z0-9.-]+$ ]] || exit 2
if [ "$(uname -s)" = Linux ]; then exec "$CORE_PACKAGE_ROOT/scripts/cli/service-linux.sh" "$CORE_SERVICE_ACTION"; fi
CORE_SERVICE_DIR="${BIZCLAW_SERVICE_DIR:-$HOME/Library/LaunchAgents}"
CORE_SERVICE_PLIST="$CORE_SERVICE_DIR/$CORE_SERVICE_LABEL.plist"
CORE_SERVICE_TARGET="gui/$(id -u)/$CORE_SERVICE_LABEL"
source "$CORE_PACKAGE_ROOT/scripts/cli/network.sh"
CORE_SERVICE_COMMAND="${BIZCLAW_SERVICE_COMMAND:-$CORE_PACKAGE_ROOT/bizclaw-core}"
core_pid_alive() {
  "$CORE_PYTHON" - "$BIZCLAW_CORE_HOME/runtime/bizclaw-core.pid" <<'PY'
import os,sys
try:
    pid=int(open(sys.argv[1]).read()); assert pid>0; os.kill(pid,0)
except (OSError,ValueError,AssertionError): sys.exit(1)
PY
}
install_service() {
  mkdir -p "$CORE_SERVICE_DIR" "$BIZCLAW_CORE_HOME/runtime"
  chmod 700 "$BIZCLAW_CORE_HOME" "$BIZCLAW_CORE_HOME/runtime"
  "$CORE_PYTHON" - "$CORE_SERVICE_PLIST" "$CORE_SERVICE_LABEL" "$CORE_SERVICE_COMMAND" "$BIZCLAW_CORE_HOME" "$CORE_SERVICE_PORT" "$CORE_SERVICE_HOST" <<'PY'
import os,plistlib,sys
p,label,command,home,port,host=sys.argv[1:]
d={'Label':label,'ProgramArguments':[command,'start','--host',host,'--port',port],
   'RunAtLoad':True,'KeepAlive':{'SuccessfulExit':False},'ThrottleInterval':10,
   'EnvironmentVariables':{'BIZCLAW_CORE_HOME':home,'BIZCLAW_SERVICE_LABEL':label,'BIZCLAW_SERVICE_DIR':os.path.dirname(p),'BIZCLAW_SERVICE_HOST':host,'BIZCLAW_SERVICE_PORT':port,'BIZCLAW_SERVICE_COMMAND':command},
   'StandardOutPath':home+'/runtime/service.log','StandardErrorPath':home+'/runtime/service-error.log'}
with open(p,'wb') as f: plistlib.dump(d,f)
os.chmod(p,0o600)
PY
}
case "$CORE_SERVICE_ACTION" in
  start|install)
    if ! launchctl print "$CORE_SERVICE_TARGET" >/dev/null 2>&1; then
      if core_pid_alive; then
        echo 'Core is already running from this data directory. Keep it running, or stop it explicitly before starting the CLI service.' >&2
        exit 2
      fi
      install_service
      launchctl bootstrap "gui/$(id -u)" "$CORE_SERVICE_PLIST"
    fi
    for attempt in {1..30}; do
      if core_pid_alive && curl --fail --silent "$CORE_SERVICE_HEALTH_URL" >/dev/null; then
        echo 'Core background service is ready.'
        core_admin_addresses
        exit 0
      fi
      sleep 1
    done
    echo "Core has not started. Check $BIZCLAW_CORE_HOME/runtime/service-error.log" >&2; exit 1 ;;
  stop|remove)
    if launchctl print "$CORE_SERVICE_TARGET" >/dev/null 2>&1; then
      launchctl bootout "$CORE_SERVICE_TARGET"
      for attempt in {1..50}; do core_pid_alive || break; sleep 0.1; done
      if core_pid_alive; then echo 'Core has not stopped yet; data retained.' >&2; exit 1; fi
    fi
    if [ "$CORE_SERVICE_ACTION" = remove ]; then rm -f "$CORE_SERVICE_PLIST"; fi
    echo 'Core CLI service stopped; business data retained.' ;;
  restart)
    "$CORE_PACKAGE_ROOT/bizclaw-core" service stop
    exec "$CORE_PACKAGE_ROOT/bizclaw-core" service start ;;
  status)
    "$CORE_PACKAGE_ROOT/bin/bun" "$CORE_PACKAGE_ROOT/src/cli.ts" status
    if launchctl print "$CORE_SERVICE_TARGET" >/dev/null 2>&1; then echo 'CLI login service: loaded'; else echo 'CLI login service: not loaded'; fi ;;
  *) echo 'Usage: bizclaw-core service start|stop|restart|status|remove' >&2; exit 2 ;;
esac
