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

REGISTRY="${LIMINAL_SHIELD_REGISTRY:-us-central1-docker.pkg.dev/cs-poc-wba485wlw0kjaig5fkxjfkj/liminal-shield}"
RAW_MODE="${LIMINAL_MODE:-human-chrome}"
STORAGE="${LIMINAL_STORAGE:-ephemeral}"
MEDIA="${LIMINAL_MEDIA:-none}"
HOST_RUNTIME="${LIMINAL_HOST_RUNTIME:-zoom-app}"
COHOST_RUNTIME="${LIMINAL_COHOST_RUNTIME:-local}"
PORT="${LIMINAL_SHIELD_PORT:-8080}"
WORKSPACE="${LIMINAL_WORKSPACE:-default}"
SAVE_DIR="${LIMINAL_SAVE_DIR:-$HOME/Liminal Shield Downloads}"
PULL_POLICY="${LIMINAL_PULL:-missing}"
OPEN_WORKSPACE="${LIMINAL_OPEN:-1}"
PLATFORM="${LIMINAL_SHIELD_PLATFORM:-}"
AUTO_PORT="${LIMINAL_AUTO_PORT:-1}"

normalize_mode() {
  case "$1" in
    desktop|human-desktop|shield-desktop) echo "human-desktop" ;;
    chrome|human-chrome|shield-chrome) echo "human-chrome" ;;
    zoom-chrome|zoom-human-chrome|human-zoom-chrome|shield-zoom-participant|shield-zoom-host-chrome) echo "human-zoom-chrome" ;;
    zoom-desktop|zoom-human-desktop|human-zoom-desktop|shield-zoom-desktop|shield-zoom-host|shield-zoom-host-desktop) echo "human-zoom-desktop" ;;
    mac-zoom|zoom-mac|native-zoom|macos-zoom) echo "mac-zoom" ;;
    zoom-bot|zoom-cohost|bot-zoom|bot-zoom-cohost|shield-zoom-sentinel|shield-zoom-sentinel-local) echo "bot-zoom-cohost" ;;
    complete|complete-zoom|shield-complete-zoom) echo "complete" ;;
    complete-local|complete-desktop|host-complete-desktop|shield-host-complete-desktop|shield-zoom-desktop-with-sentinel|shield-zoom-complete-desktop|shield-zoom-complete-local) echo "complete-local" ;;
    complete-server|shield-zoom-cloud|shield-zoom-complete-server) echo "complete-server" ;;
    *)
      echo "Unsupported LIMINAL_MODE: $1" >&2
      echo "Use one of: human-desktop, human-chrome, human-zoom-chrome, human-zoom-desktop, mac-zoom, bot-zoom-cohost, shield-zoom-desktop, shield-zoom-desktop-with-sentinel, complete" >&2
      exit 1
      ;;
  esac
}

sanitize() {
  printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9_.-' '-'
}

open_url() {
  local url="$1"
  if [[ "$OPEN_WORKSPACE" != "1" ]]; then
    return
  fi
  if command -v open >/dev/null 2>&1; then
    open "$url" >/dev/null 2>&1 || true
  elif command -v xdg-open >/dev/null 2>&1; then
    xdg-open "$url" >/dev/null 2>&1 || true
  fi
}

require_docker() {
  if ! command -v docker >/dev/null 2>&1; then
    echo "Docker is required. Install Docker Desktop, start it, then run this again." >&2
    exit 1
  fi
}

container_published_port() {
  local name="$1"
  docker port "$name" 8080/tcp 2>/dev/null | awk -F: 'NR == 1 {print $NF}'
}

port_is_free() {
  local port="$1"
  if command -v lsof >/dev/null 2>&1; then
    ! lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1
  elif command -v nc >/dev/null 2>&1; then
    ! nc -z 127.0.0.1 "$port" >/dev/null 2>&1
  else
    return 0
  fi
}

find_free_port() {
  local start="$1"
  local port="$start"
  while [[ "$port" -le 65535 ]]; do
    if port_is_free "$port"; then
      printf '%s\n' "$port"
      return 0
    fi
    port=$((port + 1))
  done
  echo "Could not find a free local port starting at $start." >&2
  exit 1
}

resolve_port() {
  local requested="$1"
  local label="${2:-port}"
  if [[ ! "$requested" =~ ^[0-9]+$ ]]; then
    echo "Unsupported $label: $requested. Use a port from 1024 to 65535." >&2
    exit 1
  fi
  if (( requested < 1024 || requested > 65535 )); then
    echo "Unsupported $label: $requested. Use a port from 1024 to 65535." >&2
    exit 1
  fi
  if port_is_free "$requested"; then
    printf '%s\n' "$requested"
    return 0
  fi
  if [[ "$AUTO_PORT" != "1" ]]; then
    echo "Local $label $requested is already in use. Set LIMINAL_SHIELD_PORT to another port or enable LIMINAL_AUTO_PORT=1." >&2
    exit 1
  fi
  local resolved
  resolved="$(find_free_port "$((requested + 1))")"
  echo "Local $label $requested is in use; using $resolved instead." >&2
  printf '%s\n' "$resolved"
}

resolve_port_pair() {
  local requested_host="$1"
  local requested_bot="$2"
  local host_port
  local bot_port
  host_port="$(resolve_port "$requested_host" "host port")"
  if [[ "$requested_bot" == "$host_port" ]]; then
    requested_bot=$((host_port + 1))
  fi
  bot_port="$(resolve_port "$requested_bot" "co-host port")"
  if [[ "$bot_port" == "$host_port" ]]; then
    bot_port="$(find_free_port "$((host_port + 1))")"
  fi
  printf '%s %s\n' "$host_port" "$bot_port"
}

validate_storage() {
  case "$1" in
    ephemeral|save-folder|persistent) ;;
    *)
      echo "Unsupported LIMINAL_STORAGE: $1" >&2
      echo "Use one of: ephemeral, save-folder, persistent" >&2
      exit 1
      ;;
  esac
}

validate_media() {
  case "$1" in
    none|allow) ;;
    *)
      echo "Unsupported LIMINAL_MEDIA: $1" >&2
      echo "Use one of: none, allow" >&2
      exit 1
      ;;
  esac
}

append_storage_args() {
  local mode="$1"
  local storage="$2"
  local workspace="$3"

  if [[ "$mode" == bot-* ]]; then
    DOCKER_ARGS+=(--read-only)
    DOCKER_ARGS+=(--tmpfs /home/shield:rw,nosuid,size=1g,uid=1000,gid=1000,mode=700)
    return
  fi

  case "$storage" in
    ephemeral)
      DOCKER_ARGS+=(--tmpfs /home/shield:rw,nosuid,size=2g,uid=1000,gid=1000,mode=700)
      ;;
    save-folder)
      mkdir -p "$SAVE_DIR"
      DOCKER_ARGS+=(--tmpfs /home/shield:rw,nosuid,size=2g,uid=1000,gid=1000,mode=700)
      DOCKER_ARGS+=(-v "$SAVE_DIR:/home/shield/Downloads")
      ;;
    persistent)
      local volume="liminal-shield-$(sanitize "$mode")-$(sanitize "$workspace")"
      DOCKER_ARGS+=(-v "$volume:/home/shield")
      ;;
  esac
}

append_media_args() {
  local mode="$1"
  local media="$2"

  if [[ "$mode" == bot-* || "$media" != "allow" ]]; then
    DOCKER_ARGS+=(-e LIMINAL_MEDIA=none)
    return
  fi

  DOCKER_ARGS+=(-e LIMINAL_MEDIA=allow)

  if [[ "$(uname -s)" != "Linux" ]]; then
    echo "Note: camera/microphone passthrough from Docker is only wired automatically for Linux hosts today." >&2
    return
  fi

  shopt -s nullglob
  local video_devices=(/dev/video*)
  shopt -u nullglob
  for device in "${video_devices[@]}"; do
    DOCKER_ARGS+=(--device "$device:$device")
  done

  local runtime_dir="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
  if [[ -S "$runtime_dir/pulse/native" ]]; then
    DOCKER_ARGS+=(-e "PULSE_SERVER=unix:/tmp/pulse-native")
    DOCKER_ARGS+=(-v "$runtime_dir/pulse/native:/tmp/pulse-native")
  fi
  if [[ -S "$runtime_dir/pipewire-0" ]]; then
    DOCKER_ARGS+=(-v "$runtime_dir/pipewire-0:/tmp/pipewire-0")
  fi
}

platform_args_for_mode() {
  local _mode="$1"
  if [[ -n "$PLATFORM" ]]; then
    printf '%s\n' "--platform" "$PLATFORM"
    return
  fi

  printf '%s\n' "--platform" "linux/amd64"
}

container_url() {
  local port="$1"
  printf 'http://127.0.0.1:%s/shield.html?autoconnect=true&resize=scale&reconnect=true' "$port"
}

run_mac_zoom_host() {
  local zoom_url="${LIMINAL_ZOOM_URL:-}"
  if [[ "$(uname -s)" != "Darwin" ]]; then
    echo "The mac-zoom host runtime only works on macOS." >&2
    exit 1
  fi

  if [[ -n "$zoom_url" ]]; then
    case "$zoom_url" in
      zoommtg://*|zoomus://*|https://zoom.us/*|https://*.zoom.us/*)
        echo "Opening Zoom meeting URL in the macOS Zoom app."
        open "$zoom_url"
        return
        ;;
      *)
        echo "Unsupported LIMINAL_ZOOM_URL: use a zoommtg://, zoomus://, or zoom.us URL." >&2
        exit 1
        ;;
    esac
  fi

  echo "Opening the macOS Zoom app."
  if open -b us.zoom.xos >/dev/null 2>&1; then
    return
  fi
  if open -a "zoom.us" >/dev/null 2>&1; then
    return
  fi

  echo "Zoom.app was not found. Install Zoom for macOS, then run this again." >&2
  echo "Download: https://zoom.us/download" >&2
  exit 1
}

run_single() {
  local mode="$1"
  local port="$2"
  local storage="$3"
  local media="$4"
  local detach="${5:-0}"
  local workspace="${6:-$WORKSPACE}"
  local image="${LIMINAL_SHIELD_IMAGE:-${REGISTRY}/${mode}:latest}"
  local name="${LIMINAL_SHIELD_NAME:-liminal-shield-${mode}}"
  local url

  if [[ "$mode" == bot-* ]]; then
    storage="ephemeral"
    media="none"
  fi

  validate_storage "$storage"
  validate_media "$media"

  if docker ps --format '{{.Names}}' | grep -qx "$name"; then
    local existing_port
    existing_port="$(container_published_port "$name")"
    if [[ -n "$existing_port" ]]; then
      port="$existing_port"
    fi
    url="$(container_url "$port")"
    echo "$name is already running."
    echo "Open: $url"
    open_url "$url"
    return
  fi

  port="$(resolve_port "$port" "port")"
  url="$(container_url "$port")"

  DOCKER_ARGS=(
    run
    --rm
    --pull="$PULL_POLICY"
    --name "$name"
    -e "SHIELD_MODE=$mode"
    -p "127.0.0.1:${port}:8080"
    --shm-size=1g
    --cap-drop=ALL
    --security-opt=no-new-privileges
    --tmpfs /tmp:rw,nosuid,size=1g
  )

  while IFS= read -r platform_arg; do
    [[ -n "$platform_arg" ]] && DOCKER_ARGS+=("$platform_arg")
  done < <(platform_args_for_mode "$mode")

  append_storage_args "$mode" "$storage" "$workspace"
  append_media_args "$mode" "$media"

  if [[ "$detach" == "1" ]]; then
    DOCKER_ARGS+=(-d)
  elif [[ -t 0 && -t 1 ]]; then
    DOCKER_ARGS+=(-it)
  fi

  DOCKER_ARGS+=("$image")

  echo "Starting $mode..."
  if [[ "$detach" != "1" ]]; then
    echo "Open: $url"
    open_url "$url"
  fi
  docker "${DOCKER_ARGS[@]}"
  if [[ "$detach" == "1" ]]; then
    echo "Open: $url"
    open_url "$url"
  fi
}

host_mode_for_runtime() {
  case "$1" in
    chrome|zoom-chrome|human-zoom-chrome) echo "human-zoom-chrome" ;;
    app|zoom-app|desktop|zoom-desktop|human-zoom-desktop) echo "human-zoom-desktop" ;;
    mac|mac-zoom|zoom-mac|native-zoom|macos-zoom) echo "mac-zoom" ;;
    *)
      echo "Unsupported LIMINAL_HOST_RUNTIME: $1" >&2
      echo "Use one of: chrome, zoom-app, mac-zoom" >&2
      exit 1
      ;;
  esac
}

validate_cohost_runtime() {
  case "$1" in
    local|server|cloud) ;;
    *)
      echo "Unsupported LIMINAL_COHOST_RUNTIME: $1" >&2
      echo "Use one of: local, server" >&2
      exit 1
      ;;
  esac
}

complete_label() {
  local host_runtime="$1"
  local cohost_runtime="$2"
  local host_mode
  host_mode="$(host_mode_for_runtime "$host_runtime")"
  if [[ "$host_mode" == "human-zoom-desktop" && "$cohost_runtime" == "local" ]]; then
    echo "Shield Zoom Desktop with Local Sentinel"
  elif [[ "$cohost_runtime" == "server" || "$cohost_runtime" == "cloud" ]]; then
    echo "Shield Zoom Desktop with Cloud Sentinel"
  else
    echo "Shield Zoom Complete"
  fi
}

run_complete() {
  local host_runtime="$1"
  local cohost_runtime="$2"
  local host_port="${LIMINAL_HOST_PORT:-$PORT}"
  local bot_port="${LIMINAL_BOT_PORT:-$((PORT + 1))}"
  local cohost_url="${LIMINAL_COHOST_SERVER_URL:-https://zoom-host-guard-coordinator-dwfg7dsmya-uc.a.run.app/}"
  local host_mode
  host_mode="$(host_mode_for_runtime "$host_runtime")"
  validate_cohost_runtime "$cohost_runtime"
  if [[ "$host_mode" == "mac-zoom" ]]; then
    if [[ "$cohost_runtime" == "local" ]]; then
      bot_port="$(resolve_port "$PORT" "co-host port")"
    fi

    echo "Starting Shield Zoom Complete for Mac."
    echo "Host runtime: macOS Zoom app"
    echo "Co-host runtime: $cohost_runtime"
    run_mac_zoom_host

    if [[ "$cohost_runtime" == "local" ]]; then
      LIMINAL_SHIELD_NAME="liminal-shield-bot-zoom-cohost" run_single "bot-zoom-cohost" "$bot_port" "ephemeral" "none" "1" "bot"
    else
      echo "Cloud co-host: $cohost_url"
      open_url "$cohost_url"
    fi

    echo
    echo "Shield Zoom Complete for Mac is running:"
    echo "  Host: macOS Zoom app"
    if [[ "$cohost_runtime" == "local" ]]; then
      echo "  Co-host: $(container_url "$bot_port")"
    else
      echo "  Cloud co-host: $cohost_url"
    fi
    return
  fi

  if [[ "$cohost_runtime" == "local" ]]; then
    read -r host_port bot_port < <(resolve_port_pair "$host_port" "$bot_port")
  else
    host_port="$(resolve_port "$host_port" "host port")"
  fi

  local product_label
  product_label="$(complete_label "$host_runtime" "$cohost_runtime")"
  echo "Starting $product_label."
  echo "Host runtime: $host_runtime on port $host_port"
  echo "Co-host runtime: $cohost_runtime"
  LIMINAL_SHIELD_NAME="liminal-shield-${host_mode}" run_single "$host_mode" "$host_port" "$STORAGE" "$MEDIA" "1" "$WORKSPACE"

  if [[ "$cohost_runtime" == "local" ]]; then
    LIMINAL_SHIELD_NAME="liminal-shield-bot-zoom-cohost" run_single "bot-zoom-cohost" "$bot_port" "ephemeral" "none" "1" "bot"
  else
    echo "Cloud co-host: $cohost_url"
    open_url "$cohost_url"
  fi

  echo
  echo "$product_label is running:"
  echo "  Host: $(container_url "$host_port")"
  if [[ "$cohost_runtime" == "local" ]]; then
    echo "  Co-host: $(container_url "$bot_port")"
  else
    echo "  Cloud co-host: $cohost_url"
  fi
}

run_complete_local() {
  run_complete "$HOST_RUNTIME" "local"
}

run_complete_server() {
  run_complete "$HOST_RUNTIME" "server"
}

main() {
  local mode
  mode="$(normalize_mode "$RAW_MODE")"

  if [[ "$mode" == "mac-zoom" ]]; then
    run_mac_zoom_host
  elif [[ "$mode" == "complete" ]]; then
    if [[ "$(host_mode_for_runtime "$HOST_RUNTIME")" != "mac-zoom" || "$COHOST_RUNTIME" == "local" ]]; then
      require_docker
    fi
    run_complete "$HOST_RUNTIME" "$COHOST_RUNTIME"
  elif [[ "$mode" == "complete-local" ]]; then
    require_docker
    run_complete_local
  elif [[ "$mode" == "complete-server" ]]; then
    if [[ "$(host_mode_for_runtime "$HOST_RUNTIME")" != "mac-zoom" ]]; then
      require_docker
    fi
    run_complete_server
  else
    require_docker
    run_single "$mode" "$PORT" "$STORAGE" "$MEDIA" "0" "$WORKSPACE"
  fi
}

main "$@"
