#!/usr/bin/env bash

set -euo pipefail

source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/oysterun_service_common.sh"

TARGET_STACKS=(production staging)
NO_START=0

xml_escape() {
  local value="$1"
  value="${value//&/&amp;}"
  value="${value//</&lt;}"
  value="${value//>/&gt;}"
  value="${value//\"/&quot;}"
  value="${value//\'/&apos;}"
  printf '%s' "${value}"
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --stack|-stack|-s)
      if [[ $# -lt 2 ]]; then
        echo "[oysterun-service] error: --stack requires a value" >&2
        exit 1
      fi
      case "$2" in
        all)
          TARGET_STACKS=(production staging)
          ;;
        *)
          STACK_NAME="$2"
          validate_stack
          TARGET_STACKS=("$2")
          ;;
      esac
      shift 2
      ;;
    --port|-port|-p)
      if [[ $# -lt 2 ]]; then
        echo "[oysterun-service] error: --port requires a value" >&2
        exit 1
      fi
      HOST_PORT_OVERRIDE="$2"
      shift 2
      ;;
    --no-start)
      NO_START=1
      shift
      ;;
    *)
      echo "[oysterun-service] error: unknown argument: $1" >&2
      exit 1
      ;;
  esac
done

if [[ -n "${HOST_PORT_OVERRIDE}" && "${#TARGET_STACKS[@]}" -gt 1 ]]; then
  echo "[oysterun-service] error: --port can only be used with one --stack target" >&2
  exit 1
fi

INSTALL_HOST_PORT_OVERRIDE="${HOST_PORT_OVERRIDE}"

NODE_BIN="$(require_node_runtime "LaunchAgent install")"

ensure_dashboard_static_app "${NODE_BIN}"

running_host_pid_for_install_stack() {
  local pid=""
  if is_macos; then
    pid="$(launchctl_pid_for_label "${HOST_LABEL}" || true)"
    if pid_is_running "${pid}"; then
      printf '%s\n' "${pid}"
      return 0
    fi
  fi
  pid="$(pid_from_file "${HOST_PID_FILE}" || true)"
  if pid_is_running "${pid}"; then
    printf '%s\n' "${pid}"
  fi
}

install_stack_agent() {
  local stack="$1"
  STACK_NAME="${stack}"
  HOST_PORT_OVERRIDE="${INSTALL_HOST_PORT_OVERRIDE}"
  BACKEND_PORT_OVERRIDE=""
  configure_stack_runtime
  require_host_port_configured
  ensure_runtime_dirs
  local running_host_pid=""
  running_host_pid="$(running_host_pid_for_install_stack)"
  if [[ -n "${running_host_pid}" ]]; then
    echo "[oysterun-service] Verifying active Host identity before service install migration for stack ${STACK_NAME}..."
    preflight_host_restart_readiness "${running_host_pid}" ""
  fi
  append_service_control_audit "service_install" "attempt" "script=tool_scripts/install_oysterun_launch_agents.sh;no_start=${NO_START}"
  sync_host_stack_port_config
  local npm_cli=""
  npm_cli="$(resolve_host_node_npm_runtime_identity write "${NODE_BIN}")"
  NODE_NPM_BUNDLE_NODE_PATH="${NODE_BIN}"
  NODE_NPM_BUNDLE_NPM_CLI_PATH="${npm_cli}"
  NODE_NPM_BUNDLE_IDENTITY_PATH="$(node_npm_runtime_identity_path)"
  local node_npm_identity_path=""
  node_npm_identity_path="$(node_npm_runtime_identity_path)"
  local launch_agent_path=""
  launch_agent_path="$(build_launch_path "${NODE_BIN}" "${CONFIG_PATH}")"

  if ! is_macos; then
    echo "[oysterun-service] Linux service mode uses the pid-file Host supervisor; no launchd LaunchAgent will be installed."
    echo "[oysterun-service] Stack:                 ${STACK_NAME}"
    echo "[oysterun-service] Host health:           ${HOST_URL}/health"
    if [[ "${NO_START}" -eq 1 ]]; then
      echo "[oysterun-service] Prepared Linux stack config without starting the Host."
      append_service_control_audit "service_install" "done" "script=tool_scripts/install_oysterun_launch_agents.sh;no_start=1;platform=linux"
      echo
      return
    fi

    local start_args=(--stack "${STACK_NAME}")
    if [[ "${STACK_KIND}" == "custom" ]]; then
      start_args+=(--port "${HOST_PORT}")
    fi
    "${ROOT_DIR}/tool_scripts/start_oysterun.sh" "${start_args[@]}"
    append_service_control_audit "service_install" "done" "script=tool_scripts/install_oysterun_launch_agents.sh;platform=linux"
    echo
    return
  fi

  local plist_path=""
  plist_path="$(launch_agent_plist_path_for_label "${HOST_LABEL}")"
  mkdir -p "$(dirname "${plist_path}")"
  # The shared deterministic renderer owns OYSTERUN_NPM_CLI and
  # OYSTERUN_NODE_NPM_IDENTITY_PATH from the verified lifecycle bundle.
  render_macos_launch_agent_definition "${plist_path}" install "${launch_agent_path}" >/dev/null

  if [[ "${NO_START}" -eq 1 ]]; then
    echo "[oysterun-service] LaunchAgent plist installed without starting: ${plist_path}"
    echo "[oysterun-service] Stack:                 ${STACK_NAME}"
    echo "[oysterun-service] Host health:           ${HOST_URL}/health"
    append_service_control_audit "service_install" "done" "script=tool_scripts/install_oysterun_launch_agents.sh;no_start=1;plist_path=${plist_path}"
    echo
    return
  fi

  if launch_service_is_loaded "${HOST_LABEL}"; then
    bootout_launch_agent_service "${HOST_LABEL}"
  fi
  stop_managed_process "${HOST_LABEL}" "${HOST_PID_FILE}" "Host service" >/dev/null 2>&1 || true
  stop_stale_stack_host_state_holders "during LaunchAgent install"
  clear_host_origin_file
  ensure_port_available "${HOST_PORT}"
  prepare_host_log_for_service_start "${HOST_LOG}" "Host service"

  echo "[oysterun-service] Installing LaunchAgent for ${STACK_NAME} on ${HOST_URL}..."
  bootstrap_launch_agent_plist "${plist_path}"
  wait_for_http "${HOST_URL}/health" "Host service" "$(launchctl_pid_for_label "${HOST_LABEL}")" "${HOST_LOG}" "${HOST_LABEL}"

  local host_pid=""
  host_pid="$(pid_from_file "${HOST_PID_FILE}")"
  if [[ -z "${host_pid}" ]]; then
    host_pid="$(launchctl_pid_for_label "${HOST_LABEL}")"
  fi

  echo "[oysterun-service] LaunchAgent installed: ${plist_path}"
  echo "[oysterun-service] Stack:                 ${STACK_NAME}"
  echo "[oysterun-service] Host health:           ${HOST_URL}/health"
  echo "[oysterun-service] Host PID:              ${host_pid}"
  append_service_control_audit "service_install" "done" "script=tool_scripts/install_oysterun_launch_agents.sh;plist_path=${plist_path};host_pid=${host_pid}"
  echo
}

for stack in "${TARGET_STACKS[@]}"; do
  install_stack_agent "${stack}"
done
