#!/bin/sh
set -eu

CONFIG_PATH="/etc/photobooth/config.yml"
FALLBACK_URL="http://127.0.0.1:1610"
CHROMIUM_POLICY_DIR="/etc/chromium/policies/managed"
CHROMIUM_DISABLE_TRANSLATE_POLICY="$CHROMIUM_POLICY_DIR/disable-translate.json"
KIOSK_DEBUG_HOST="127.0.0.1"
KIOSK_DEBUG_PORT="9222"

print_help() {
  cat <<'EOF'
photobooth help
  Show all available commands with a short description.

photobooth config-path
  Print the path to the active photobooth config file.

photobooth config-show
  Print the current config file to the terminal.

photobooth edit-config
  Open the config file in nano when available, otherwise fall back to $EDITOR.

photobooth fix-gphoto2-automount
  Stop active gvfs gphoto2 automount processes and mask the volume-monitor service for future boots.

photobooth kiosk status
  Reserved for a future kiosk status command (not implemented yet).

photobooth kiosk install --user <linux-user> [--url <url>] [--browser <browser>]
  Install Raspberry Pi OS kiosk autologin + browser fullscreen startup for the given desktop user.
  Without --url, the command uses server.bind/server.port from config.yml and falls back to the local default URL.

photobooth kiosk fix-waiting-page
  Rewrite the global kiosk waiting page with the target URL from config.yml.
  Uses server.bind/server.port from config.yml and falls back to the local default URL.

photobooth kiosk leave
  Close the currently running Photobooth kiosk browser.

photobooth kiosk open-devtools
  Open Chrome DevTools for the currently running Photobooth kiosk browser.
EOF
}

require_root() {
  if [ "$(id -u)" -ne 0 ]; then
    echo "This command must be run as root." >&2
    exit 1
  fi
}

ensure_config_exists() {
  if [ ! -f "$CONFIG_PATH" ]; then
    echo "Config file not found: $CONFIG_PATH" >&2
    exit 1
  fi
}

ensure_supported_os() {
  if [ ! -r /etc/os-release ]; then
    echo "Unsupported OS: /etc/os-release not found." >&2
    exit 1
  fi

  if ! grep -qi "raspbian\|Raspberry Pi OS" /etc/os-release \
    && ! (grep -qi '^ID="\?debian"\?$' /etc/os-release \
      && grep -qi '^VERSION_CODENAME="\?trixie"\?$' /etc/os-release); then
    echo "Unsupported OS: kiosk install currently supports Raspberry Pi OS (including Debian 13/Trixie images) only." >&2
    exit 1
  fi

  if ! command -v raspi-config >/dev/null 2>&1; then
    echo "Unsupported OS: raspi-config is required for kiosk install." >&2
    exit 1
  fi
}

open_config() {
  ensure_config_exists

  if command -v nano >/dev/null 2>&1; then
    exec nano "$CONFIG_PATH"
  fi

  if [ -n "${EDITOR:-}" ] && command -v "$EDITOR" >/dev/null 2>&1; then
    exec "$EDITOR" "$CONFIG_PATH"
  fi

  echo "nano is not installed and \$EDITOR is not set to a valid editor." >&2
  echo "Install nano with: sudo apt install nano" >&2
  exit 1
}

show_config() {
  ensure_config_exists
  cat "$CONFIG_PATH"
}

fix_gphoto2_automount() {
  require_root

  if ! command -v systemctl >/dev/null 2>&1; then
    echo "systemctl is required to manage gvfs gphoto2 automount services." >&2
    exit 1
  fi

  UNIT_NAME="gvfs-gphoto2-volume-monitor.service"
  MASKED_ANY=0

  echo "Applying gphoto2 automount fix for: $UNIT_NAME"

  if command -v pkill >/dev/null 2>&1; then
    pkill -f gvfs-gphoto2-volume-monitor || true
  fi

  if systemctl stop "$UNIT_NAME" >/dev/null 2>&1; then
    echo "Stopped system unit: $UNIT_NAME"
  else
    echo "System unit was not running or is not available: $UNIT_NAME"
  fi

  if systemctl mask "$UNIT_NAME" >/dev/null 2>&1; then
    echo "Masked system unit: $UNIT_NAME"
    MASKED_ANY=1
  fi

  if systemctl --global mask "$UNIT_NAME" >/dev/null 2>&1; then
    echo "Masked global user unit: $UNIT_NAME"
    MASKED_ANY=1
  fi

  if [ "$MASKED_ANY" -eq 0 ]; then
    echo "Could not mask $UNIT_NAME with systemctl." >&2
    exit 1
  fi

  echo "gphoto2 automount fix applied. Reboot or log in again to pick up the change."
}

write_managed_block() {
  TARGET_PATH="$1"
  BLOCK_PATH="$2"
  START_MARKER="# >>> photobooth kiosk >>>"
  END_MARKER="# <<< photobooth kiosk <<<"
  TMP_PATH=$(mktemp)

  if [ -f "$TARGET_PATH" ]; then
    awk -v start="$START_MARKER" -v end="$END_MARKER" '
      $0 == start { skip = 1; next }
      $0 == end { skip = 0; next }
      !skip { print }
    ' "$TARGET_PATH" > "$TMP_PATH"
  else
    : > "$TMP_PATH"
  fi

  cat "$BLOCK_PATH" >> "$TMP_PATH"
  install -m 0644 "$TMP_PATH" "$TARGET_PATH"
  rm -f "$TMP_PATH"
}

resolve_browser_package() {
  REQUESTED_BROWSER="${1:-}"

  is_installable() {
    apt-cache policy "$1" 2>/dev/null | grep -q '^  Candidate: ' \
      && ! apt-cache policy "$1" 2>/dev/null | grep -q '^  Candidate: (none)$'
  }

  case "$REQUESTED_BROWSER" in
    ""|chromium)
      if is_installable chromium; then
        printf '%s\n' chromium
        return 0
      fi
      if [ -z "$REQUESTED_BROWSER" ] && is_installable chromium-browser; then
        printf '%s\n' chromium-browser
        return 0
      fi
      ;;
    chromium-browser)
      if is_installable chromium-browser; then
        printf '%s\n' chromium-browser
        return 0
      fi
      ;;
  esac

  if [ -n "$REQUESTED_BROWSER" ]; then
    echo "Unsupported browser: $REQUESTED_BROWSER. Supported values are chromium and chromium-browser." >&2
  else
    echo "Unsupported OS: neither chromium nor chromium-browser is installable via apt." >&2
  fi
  exit 1
}

resolve_desktop_dir() {
  USER_HOME="$1"
  USER_DIRS_FILE="$USER_HOME/.config/user-dirs.dirs"
  DESKTOP_DIR="$USER_HOME/Desktop"

  if [ -f "$USER_DIRS_FILE" ]; then
    DESKTOP_SETTING=$(awk -F= '/^XDG_DESKTOP_DIR=/{print $2}' "$USER_DIRS_FILE" | tail -n1 | tr -d '"')
    if [ -n "$DESKTOP_SETTING" ]; then
      case "$DESKTOP_SETTING" in
        \$HOME/*)
          DESKTOP_DIR="$USER_HOME/${DESKTOP_SETTING#\$HOME/}"
          ;;
        "$USER_HOME"/*)
          DESKTOP_DIR="$DESKTOP_SETTING"
          ;;
      esac
    fi
  fi

  printf '%s\n' "$DESKTOP_DIR"
}

escape_js_string() {
  printf '%s' "$1" | sed \
    -e 's/\\/\\\\/g' \
    -e 's/"/\\"/g' \
    -e 's/&/\\u0026/g' \
    -e 's/</\\u003C/g' \
    -e 's/>/\\u003E/g'
}

escape_sed_replacement() {
  printf '%s' "$1" | sed -e 's/[\\&|]/\\&/g'
}

read_config_section_scalar() {
  section="$1"
  key="$2"

  if [ ! -f "$CONFIG_PATH" ]; then
    return 1
  fi

  in_section=0

  while IFS= read -r line || [ -n "$line" ]; do
    trimmed_line=$(printf '%s' "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')

    case "$trimmed_line" in
      ''|\#*)
        continue
        ;;
    esac

    if [ "$in_section" -eq 0 ]; then
      if [ "$trimmed_line" = "$section:" ]; then
        in_section=1
      fi
      continue
    fi

    case "$line" in
      [![:space:]]*)
        break
        ;;
    esac

    case "$trimmed_line" in
      "$key":*)
        value=${trimmed_line#"$key":}
        value=$(printf '%s' "$value" | sed -e 's/[[:space:]]*#.*$//' -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')

        case "$value" in
          \"*\")
            value=${value#\"}
            value=${value%\"}
            ;;
          \'*\')
            value=${value#\'}
            value=${value%\'}
            ;;
        esac

        printf '%s\n' "$value"
        return 0
        ;;
    esac
  done < "$CONFIG_PATH"

  return 1
}

normalize_kiosk_host() {
  host="$1"

  case "$host" in
    0.0.0.0|::|[::])
      printf '%s\n' "127.0.0.1"
      ;;
    *:*)
      case "$host" in
        \[*\])
          printf '%s\n' "$host"
          ;;
        *)
          printf '[%s]\n' "$host"
          ;;
      esac
      ;;
    *)
      printf '%s\n' "$host"
      ;;
  esac
}

resolve_kiosk_url_from_config() {
  bind=$(read_config_section_scalar server bind || true)
  port=$(read_config_section_scalar server port || true)

  if [ -z "$bind" ] || [ -z "$port" ]; then
    return 1
  fi

  case "$port" in
    *[!0-9]*|'')
      return 1
      ;;
  esac

  host=$(normalize_kiosk_host "$bind")
  if [ -z "$host" ]; then
    return 1
  fi

  printf 'http://%s:%s\n' "$host" "$port"
}

resolve_kiosk_url() {
  requested_url="${1:-}"

  if [ -n "$requested_url" ]; then
    printf '%s\n' "$requested_url"
    return 0
  fi

  configured_url=$(resolve_kiosk_url_from_config || true)
  if [ -n "$configured_url" ]; then
    printf '%s\n' "$configured_url"
    return 0
  fi

  printf '%s\n' "$FALLBACK_URL"
}

resolve_kiosk_user_home() {
  KIOSK_USER="$1"

  if ! id "$KIOSK_USER" >/dev/null 2>&1; then
    echo "Linux user not found: $KIOSK_USER" >&2
    exit 1
  fi

  USER_HOME=$(getent passwd "$KIOSK_USER" | cut -d: -f6)
  if [ -z "$USER_HOME" ] || [ ! -d "$USER_HOME" ]; then
    echo "Could not determine a valid home directory for user: $KIOSK_USER" >&2
    exit 1
  fi

  printf '%s\n' "$USER_HOME"
}

render_kiosk_waiting_page() {
  KIOSK_URL="$1"
  KIOSK_WAITING_SOURCE="/usr/share/photobooth/kiosk-waiting.html"
  KIOSK_WAITING_PAGE="/var/lib/photobooth/kiosk-waiting.html"
  KIOSK_WAITING_DIR=$(dirname "$KIOSK_WAITING_PAGE")
  KIOSK_URL_JS=$(escape_js_string "$KIOSK_URL")
  KIOSK_URL_JS_SED=$(escape_sed_replacement "$KIOSK_URL_JS")
  TMP_PATH=$(mktemp)

  if [ ! -f "$KIOSK_WAITING_SOURCE" ]; then
    echo "Kiosk waiting-page HTML not found: $KIOSK_WAITING_SOURCE" >&2
    rm -f "$TMP_PATH"
    exit 1
  fi

  if grep -q '__KIOSK_URL__' "$KIOSK_WAITING_SOURCE"; then
    sed "s|__KIOSK_URL__|$KIOSK_URL_JS_SED|g" "$KIOSK_WAITING_SOURCE" > "$TMP_PATH"
  elif grep -Eq 'const[[:space:]]+targetUrl[[:space:]]*=' "$KIOSK_WAITING_SOURCE"; then
    echo "Kiosk waiting-page template marker missing; patching existing target URL assignment." >&2
    sed -E "s|^[[:space:]]*const[[:space:]]+targetUrl[[:space:]]*=.*$|    const targetUrl = \"$KIOSK_URL_JS_SED\";|" "$KIOSK_WAITING_SOURCE" > "$TMP_PATH"
  else
    echo "Kiosk waiting-page template does not contain a target URL placeholder or assignment." >&2
    rm -f "$TMP_PATH"
    exit 1
  fi

  install -d -m 0755 "$KIOSK_WAITING_DIR"

  if id photobooth-service >/dev/null 2>&1 && getent group photobooth-service >/dev/null 2>&1; then
    install -o photobooth-service -g photobooth-service -m 0644 "$TMP_PATH" "$KIOSK_WAITING_PAGE"
  else
    install -m 0644 "$TMP_PATH" "$KIOSK_WAITING_PAGE"
  fi

  rm -f "$TMP_PATH"

  printf '%s\n' "$KIOSK_WAITING_PAGE"
}

install_chromium_disable_translate_policy() {
  TMP_PATH=$(mktemp)

  cat > "$TMP_PATH" <<'EOF'
{
  "TranslateEnabled": false
}
EOF

  install -d -m 0755 "$CHROMIUM_POLICY_DIR"
  install -m 0644 "$TMP_PATH" "$CHROMIUM_DISABLE_TRANSLATE_POLICY"
  rm -f "$TMP_PATH"
}

fix_kiosk_waiting_page() {
  require_root

  if [ "$#" -gt 0 ]; then
    echo "Usage: photobooth kiosk fix-waiting-page" >&2
    exit 1
  fi

  KIOSK_URL=$(resolve_kiosk_url "")
  KIOSK_WAITING_PAGE=$(render_kiosk_waiting_page "$KIOSK_URL")

  echo "Kiosk waiting page fixed from global config."
  echo "Configured URL: $KIOSK_URL"
  echo "Updated waiting page: $KIOSK_WAITING_PAGE"
}

find_kiosk_browser_pid() {
  for PATTERN in \
    'chromium.*--kiosk.*photobooth' \
    'chromium-browser.*--kiosk.*photobooth' \
    'google-chrome.*--kiosk.*photobooth' \
    'chrome.*--kiosk.*photobooth'
  do
    PID=$(pgrep -f "$PATTERN" | head -n 1 || true)
    if [ -n "$PID" ]; then
      printf '%s\n' "$PID"
      return 0
    fi
  done

  return 1
}

read_process_env_var() {
  PID="$1"
  KEY="$2"
  ENV_PATH="/proc/$PID/environ"

  if [ ! -r "$ENV_PATH" ]; then
    return 1
  fi

  tr '\0' '\n' < "$ENV_PATH" | awk -v key="$KEY" '
    index($0, key "=") == 1 {
      sub(key "=", "", $0)
      print
      exit
    }
  '
}

read_process_arg0() {
  PID="$1"
  CMDLINE_PATH="/proc/$PID/cmdline"

  if [ ! -r "$CMDLINE_PATH" ]; then
    return 1
  fi

  tr '\0' '\n' < "$CMDLINE_PATH" | head -n 1
}

resolve_user_runtime_dir() {
  USER_NAME="$1"
  PID="${2:-}"
  RUNTIME_DIR=""

  if [ -n "$PID" ]; then
    RUNTIME_DIR=$(read_process_env_var "$PID" XDG_RUNTIME_DIR || true)
  fi

  if [ -n "$RUNTIME_DIR" ] && [ -d "$RUNTIME_DIR" ]; then
    printf '%s\n' "$RUNTIME_DIR"
    return 0
  fi

  USER_ID=$(id -u "$USER_NAME" 2>/dev/null || true)
  if [ -n "$USER_ID" ] && [ -d "/run/user/$USER_ID" ]; then
    printf '/run/user/%s\n' "$USER_ID"
    return 0
  fi

  return 1
}

resolve_wayland_display_from_runtime_dir() {
  RUNTIME_DIR="$1"

  for CANDIDATE in wayland-0 wayland-1; do
    if [ -S "$RUNTIME_DIR/$CANDIDATE" ]; then
      printf '%s\n' "$CANDIDATE"
      return 0
    fi
  done

  for WAYLAND_SOCKET in "$RUNTIME_DIR"/wayland-*; do
    if [ -S "$WAYLAND_SOCKET" ]; then
      printf '%s\n' "${WAYLAND_SOCKET##*/}"
      return 0
    fi
  done

  return 1
}

resolve_x11_display() {
  for DISPLAY_ID in 0 1; do
    if [ -S "/tmp/.X11-unix/X$DISPLAY_ID" ]; then
      printf ':%s\n' "$DISPLAY_ID"
      return 0
    fi
  done

  return 1
}

resolve_dbus_session_bus_address() {
  RUNTIME_DIR="$1"

  if [ -n "$RUNTIME_DIR" ] && [ -S "$RUNTIME_DIR/bus" ]; then
    printf 'unix:path=%s/bus\n' "$RUNTIME_DIR"
    return 0
  fi

  return 1
}

resolve_browser_bin_from_pid() {
  PID="$1"
  BROWSER_BIN=$(read_process_arg0 "$PID" || true)

  if [ -n "$BROWSER_BIN" ] && [ -x "$BROWSER_BIN" ]; then
    printf '%s\n' "$BROWSER_BIN"
    return 0
  fi

  BROWSER_BIN=$(readlink -f "/proc/$PID/exe" 2>/dev/null || true)
  if [ -n "$BROWSER_BIN" ] && [ -x "$BROWSER_BIN" ]; then
    printf '%s\n' "$BROWSER_BIN"
    return 0
  fi

  for CANDIDATE in /usr/bin/chromium /usr/bin/chromium-browser /usr/bin/google-chrome /usr/bin/chrome
  do
    if [ -x "$CANDIDATE" ]; then
      printf '%s\n' "$CANDIDATE"
      return 0
    fi
  done

  echo "Could not resolve the active kiosk browser binary." >&2
  return 1
}

fetch_kiosk_devtools_url() {
  if ! command -v node >/dev/null 2>&1; then
    echo "node is required to resolve the Chrome DevTools target." >&2
    return 1
  fi

  KIOSK_DEBUG_HOST="$KIOSK_DEBUG_HOST" KIOSK_DEBUG_PORT="$KIOSK_DEBUG_PORT" node <<'NODE'
const http = require('node:http')

const host = process.env.KIOSK_DEBUG_HOST || '127.0.0.1'
const port = Number(process.env.KIOSK_DEBUG_PORT || '9222')

const request = http.get({ host, port, path: '/json/list', timeout: 1200 }, (response) => {
  let body = ''
  response.setEncoding('utf8')
  response.on('data', (chunk) => {
    body += chunk
  })
  response.on('end', () => {
    try {
      const targets = JSON.parse(body)
      const pages = targets.filter((target) => {
        return (
          target &&
          target.type === 'page' &&
          typeof target.url === 'string' &&
          !target.url.startsWith('devtools://') &&
          (target.devtoolsFrontendUrl || target.webSocketDebuggerUrl)
        )
      })
      const target =
        pages.find((page) => /photobooth|127\.0\.0\.1|localhost/.test(page.url)) || pages[0]

      if (!target) {
        process.exit(2)
      }

      if (target.devtoolsFrontendUrl) {
        console.log(new URL(target.devtoolsFrontendUrl, `http://${host}:${port}`).href)
        return
      }

      const websocketPath = target.webSocketDebuggerUrl.replace(/^ws:\/\//, '')
      console.log(`http://${host}:${port}/devtools/inspector.html?ws=${websocketPath}`)
    } catch {
      process.exit(1)
    }
  })
})

request.on('timeout', () => {
  request.destroy()
})
request.on('error', () => {
  process.exit(1)
})
NODE
}

open_kiosk_devtools() {
  require_root

  if [ "$#" -gt 0 ]; then
    echo "Usage: photobooth kiosk open-devtools" >&2
    exit 1
  fi

  if ! command -v pgrep >/dev/null 2>&1; then
    echo "pgrep is required to find the kiosk browser." >&2
    exit 1
  fi

  KIOSK_PID=$(find_kiosk_browser_pid || true)
  if [ -z "$KIOSK_PID" ]; then
    echo "No active Photobooth kiosk browser found." >&2
    exit 1
  fi

  DEVTOOLS_URL=$(fetch_kiosk_devtools_url || true)
  if [ -z "$DEVTOOLS_URL" ]; then
    echo "No Chrome DevTools target found on ${KIOSK_DEBUG_HOST}:${KIOSK_DEBUG_PORT}." >&2
    echo "Reinstall or restart kiosk mode so Chromium starts with the Photobooth debug endpoint." >&2
    exit 1
  fi

  KIOSK_USER=$(ps -o user= -p "$KIOSK_PID" | awk '{ print $1 }' | head -n 1)
  if [ -z "$KIOSK_USER" ]; then
    echo "Could not resolve the kiosk browser user." >&2
    exit 1
  fi

  USER_HOME=$(resolve_kiosk_user_home "$KIOSK_USER")
  USER_GROUP=$(id -gn "$KIOSK_USER")
  BROWSER_BIN=$(resolve_browser_bin_from_pid "$KIOSK_PID")
  XDG_RUNTIME_DIR_VALUE=$(resolve_user_runtime_dir "$KIOSK_USER" "$KIOSK_PID" || true)
  DISPLAY_VALUE=$(read_process_env_var "$KIOSK_PID" DISPLAY || true)
  WAYLAND_DISPLAY_VALUE=$(read_process_env_var "$KIOSK_PID" WAYLAND_DISPLAY || true)
  DBUS_SESSION_BUS_ADDRESS_VALUE=$(read_process_env_var "$KIOSK_PID" DBUS_SESSION_BUS_ADDRESS || true)

  if [ -z "$WAYLAND_DISPLAY_VALUE" ] && [ -n "$XDG_RUNTIME_DIR_VALUE" ]; then
    WAYLAND_DISPLAY_VALUE=$(resolve_wayland_display_from_runtime_dir "$XDG_RUNTIME_DIR_VALUE" || true)
  fi

  if [ -z "$DISPLAY_VALUE" ] && [ -z "$WAYLAND_DISPLAY_VALUE" ]; then
    DISPLAY_VALUE=$(resolve_x11_display || true)
  fi

  if [ -z "$DBUS_SESSION_BUS_ADDRESS_VALUE" ] && [ -n "$XDG_RUNTIME_DIR_VALUE" ]; then
    DBUS_SESSION_BUS_ADDRESS_VALUE=$(resolve_dbus_session_bus_address "$XDG_RUNTIME_DIR_VALUE" || true)
  fi

  if [ -z "$DISPLAY_VALUE" ] && [ -z "$WAYLAND_DISPLAY_VALUE" ]; then
    echo "Could not resolve the kiosk browser display session from Chromium env, Wayland sockets, or X11 sockets." >&2
    exit 1
  fi

  DEVTOOLS_PROFILE="$USER_HOME/.cache/photobooth-devtools"
  install -d -o "$KIOSK_USER" -g "$USER_GROUP" -m 0700 "$DEVTOOLS_PROFILE"

  ENV_ARGS="HOME=$USER_HOME"
  if [ -n "$DISPLAY_VALUE" ]; then
    ENV_ARGS="$ENV_ARGS DISPLAY=$DISPLAY_VALUE"
  fi
  if [ -n "$WAYLAND_DISPLAY_VALUE" ]; then
    ENV_ARGS="$ENV_ARGS WAYLAND_DISPLAY=$WAYLAND_DISPLAY_VALUE"
  fi
  if [ -n "$XDG_RUNTIME_DIR_VALUE" ]; then
    ENV_ARGS="$ENV_ARGS XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR_VALUE"
  fi
  if [ -n "$DBUS_SESSION_BUS_ADDRESS_VALUE" ]; then
    ENV_ARGS="$ENV_ARGS DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS_VALUE"
  fi

  LAUNCH_PREFIX=""
  if command -v setsid >/dev/null 2>&1; then
    LAUNCH_PREFIX="setsid"
  fi

  if command -v runuser >/dev/null 2>&1; then
    runuser -u "$KIOSK_USER" -- env $ENV_ARGS $LAUNCH_PREFIX "$BROWSER_BIN" \
      --user-data-dir="$DEVTOOLS_PROFILE" \
      --new-window \
      --start-maximized \
      --no-first-run \
      --no-default-browser-check \
      "$DEVTOOLS_URL" >/dev/null 2>&1 &
  elif command -v sudo >/dev/null 2>&1; then
    sudo -u "$KIOSK_USER" env $ENV_ARGS $LAUNCH_PREFIX "$BROWSER_BIN" \
      --user-data-dir="$DEVTOOLS_PROFILE" \
      --new-window \
      --start-maximized \
      --no-first-run \
      --no-default-browser-check \
      "$DEVTOOLS_URL" >/dev/null 2>&1 &
  else
    echo "runuser or sudo is required to open DevTools in the kiosk desktop session." >&2
    exit 1
  fi

  echo "Chrome DevTools open requested."
}

leave_kiosk() {
  require_root

  if ! command -v pgrep >/dev/null 2>&1 || ! command -v pkill >/dev/null 2>&1; then
    echo "pgrep and pkill are required to close the kiosk browser." >&2
    exit 1
  fi

  MATCHED=0
  for PATTERN in \
    'chromium.*--kiosk.*photobooth' \
    'chromium-browser.*--kiosk.*photobooth' \
    'google-chrome.*--kiosk.*photobooth' \
    'chrome.*--kiosk.*photobooth'
  do
    if pgrep -f "$PATTERN" >/dev/null 2>&1; then
      pkill -TERM -f "$PATTERN" || true
      MATCHED=1
    fi
  done

  if [ "$MATCHED" -eq 0 ]; then
    echo "No active Photobooth kiosk browser found."
  else
    echo "Photobooth kiosk browser close requested."
  fi
}

install_kiosk() {
  require_root
  ensure_supported_os

  KIOSK_USER=""
  KIOSK_URL=""
  KIOSK_BROWSER="chromium"

  while [ "$#" -gt 0 ]; do
    case "$1" in
      --user)
        [ "$#" -ge 2 ] || { echo "Missing value for --user" >&2; exit 1; }
        KIOSK_USER="$2"
        shift 2
        ;;
      --url)
        [ "$#" -ge 2 ] || { echo "Missing value for --url" >&2; exit 1; }
        KIOSK_URL="$2"
        shift 2
        ;;
      --browser)
        [ "$#" -ge 2 ] || { echo "Missing value for --browser" >&2; exit 1; }
        KIOSK_BROWSER="$2"
        shift 2
        ;;
      *)
        echo "Unknown kiosk install option: $1" >&2
        exit 1
        ;;
    esac
  done

  if [ -z "$KIOSK_USER" ]; then
    echo "Usage: photobooth kiosk install --user <linux-user> [--url <url>] [--browser <browser>]" >&2
    exit 1
  fi

  KIOSK_URL=$(resolve_kiosk_url "$KIOSK_URL")
  USER_HOME=$(resolve_kiosk_user_home "$KIOSK_USER")

  apt update

  BROWSER_PACKAGE=$(resolve_browser_package "$KIOSK_BROWSER")

  DEBIAN_FRONTEND=noninteractive apt install -y \
    "$BROWSER_PACKAGE" \
    ca-certificates \
    nano

  install_chromium_disable_translate_policy

  USER_GROUP=$(id -gn "$KIOSK_USER")
  DESKTOP_DIR=$(resolve_desktop_dir "$USER_HOME")
  KIOSK_WAITING_PAGE=$(render_kiosk_waiting_page "$KIOSK_URL")
  KIOSK_WAITING_PAGE_URL="file://$KIOSK_WAITING_PAGE"

  install -d -o "$KIOSK_USER" -g "$USER_GROUP" -m 0755 "$USER_HOME/.local/bin"
  install -d -o "$KIOSK_USER" -g "$USER_GROUP" -m 0755 "$USER_HOME/.config/autostart"
  install -d -o "$KIOSK_USER" -g "$USER_GROUP" -m 0755 "$USER_HOME/.config/labwc"
  install -d -o "$KIOSK_USER" -g "$USER_GROUP" -m 0755 "$USER_HOME/.cache"
  install -d -o "$KIOSK_USER" -g "$USER_GROUP" -m 0755 "$DESKTOP_DIR"

  cat > "$USER_HOME/.local/bin/photobooth-kiosk.sh" <<EOF
#!/usr/bin/env bash
set -euo pipefail

BROWSER_PACKAGE="${BROWSER_PACKAGE}"
WAITING_PAGE_URL="${KIOSK_WAITING_PAGE_URL}"
LOCK_DIR="\${XDG_RUNTIME_DIR:-$USER_HOME/.cache}"
LOCK_PATH="\${LOCK_DIR}/photobooth-kiosk.lock"

mkdir -p "\$LOCK_DIR"
exec 9>"\$LOCK_PATH"
if ! flock -n 9; then
  exit 0
fi

case "\$BROWSER_PACKAGE" in
  chromium)
    BROWSER_BIN="/usr/bin/chromium"
    ;;
  chromium-browser)
    BROWSER_BIN="/usr/bin/chromium-browser"
    ;;
  *)
    BROWSER_BIN="/usr/bin/\$BROWSER_PACKAGE"
    ;;
esac

if [ ! -x "\$BROWSER_BIN" ]; then
  echo "Browser binary not found for package: \$BROWSER_PACKAGE" >&2
  exit 1
fi

exec "\$BROWSER_BIN" \
  --kiosk \
  --incognito \
  --noerrdialogs \
  --disable-infobars \
  --disable-session-crashed-bubble \
  --no-first-run \
  --remote-debugging-address=${KIOSK_DEBUG_HOST} \
  --remote-debugging-port=${KIOSK_DEBUG_PORT} \
  --enable-features=OverlayScrollbar \
  --overscroll-history-navigation=0 \
  --disable-pinch \
  --start-maximized \
  --password-store=basic \
  "\${WAITING_PAGE_URL}"
EOF
  chmod 0755 "$USER_HOME/.local/bin/photobooth-kiosk.sh"

  cat > "$USER_HOME/.config/autostart/photobooth-kiosk.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=Photobooth Kiosk
Exec=$USER_HOME/.local/bin/photobooth-kiosk.sh
Terminal=false
X-GNOME-Autostart-enabled=true
EOF

  cat > "$DESKTOP_DIR/photobooth-kiosk.desktop" <<EOF
[Desktop Entry]
Type=Application
Version=1.0
Name=Photobooth Kiosk
Comment=Restart the photobooth kiosk browser
Exec=$USER_HOME/.local/bin/photobooth-kiosk.sh
Terminal=false
Icon=web-browser
Categories=Utility;
StartupNotify=false
EOF
  chmod 0755 "$DESKTOP_DIR/photobooth-kiosk.desktop"
  chown "$KIOSK_USER:$USER_GROUP" "$DESKTOP_DIR/photobooth-kiosk.desktop"

  LABWC_BLOCK=$(mktemp)
  cat > "$LABWC_BLOCK" <<EOF
# >>> photobooth kiosk >>>
$USER_HOME/.local/bin/photobooth-kiosk.sh &
# <<< photobooth kiosk <<<
EOF
  write_managed_block "$USER_HOME/.config/labwc/autostart" "$LABWC_BLOCK"
  rm -f "$LABWC_BLOCK"

  chown -R "$KIOSK_USER:$USER_GROUP" "$USER_HOME/.local" "$USER_HOME/.config/autostart" "$USER_HOME/.config/labwc" "$USER_HOME/.cache"

  raspi-config nonint do_boot_behaviour B4

  echo "Kiosk mode files installed for user: $KIOSK_USER"
  echo "Configured URL: $KIOSK_URL"
  echo "Startup waiting page: $KIOSK_WAITING_PAGE"
  echo "Configured browser package: $BROWSER_PACKAGE"
  echo "Chromium policy: $CHROMIUM_DISABLE_TRANSLATE_POLICY"
  echo "Desktop launcher: $DESKTOP_DIR/photobooth-kiosk.desktop"
  echo "Installed startup hooks for current Raspberry Pi OS Desktop (labwc) plus desktop autostart fallback."
  echo "Desktop autologin has been enabled. Reboot the system to test the kiosk startup."
}

COMMAND="${1:-help}"
case "$COMMAND" in
  help|-h|--help)
    print_help
    ;;
  config-path)
    printf '%s\n' "$CONFIG_PATH"
    ;;
  edit-config)
    open_config
    ;;
  config-show)
    show_config
    ;;
  fix-gphoto2-automount)
    fix_gphoto2_automount
    ;;
  kiosk)
    SUBCOMMAND="${2:-}"
    case "$SUBCOMMAND" in
      status)
        echo "photobooth kiosk status is not implemented yet."
        exit 1
        ;;
      install)
        shift 2
        install_kiosk "$@"
        ;;
      fix-waiting-page)
        shift 2
        fix_kiosk_waiting_page "$@"
        ;;
      leave)
        shift 2
        leave_kiosk "$@"
        ;;
      open-devtools)
        shift 2
        open_kiosk_devtools "$@"
        ;;
      *)
        echo "Unknown kiosk subcommand: ${SUBCOMMAND:-<missing>}" >&2
        echo "Run 'photobooth help' for usage." >&2
        exit 1
        ;;
    esac
    ;;
  '')
    print_help
    ;;
  *)
    echo "Unknown command: $COMMAND" >&2
    echo "Run 'photobooth help' for usage." >&2
    exit 1
    ;;
esac
