#!/bin/sh
set -eu
if [ "${ORBITMESH_EDGE_RELEASE_ID:-orbitmesh}" != 'orbitmesh' ]; then printf 'Edge release identity mismatch\n' >&2; exit 1; fi
if [ "${ORBITMESH_EDGE_RELEASE_ID+x}" != x ]; then ORBITMESH_EDGE_RELEASE_ID='orbitmesh'; fi
if [ "${ORBITMESH_INSTANCE_ID+x}" != x ]; then ORBITMESH_INSTANCE_ID='agentdeploy'; fi
if [ "${ORBITMESH_PRODUCT_NAME+x}" != x ]; then ORBITMESH_PRODUCT_NAME='AgentDeploy'; fi
if [ "${ORBITMESH_CONTROL_PLANE_URL+x}" != x ]; then ORBITMESH_CONTROL_PLANE_URL='https://api.agent-deploy.ai'; fi
if [ "${ORBITMESH_EDGE_RUNTIME_DOWNLOAD_PREFIX+x}" != x ]; then ORBITMESH_EDGE_RUNTIME_DOWNLOAD_PREFIX='https://pkgs.orbitmesh.dev/edge-runtime/latest'; fi
if [ "${ORBITMESH_UPDATE_SOURCE_MODE+x}" != x ]; then ORBITMESH_UPDATE_SOURCE_MODE='shared'; fi
if [ "${ORBITMESH_UPDATE_BASE_URL+x}" != x ]; then ORBITMESH_UPDATE_BASE_URL='https://pkgs.orbitmesh.dev/edge-runtime'; fi
if [ "${ORBITMESH_UPDATE_MANIFEST_URL+x}" != x ]; then ORBITMESH_UPDATE_MANIFEST_URL=''; fi
if [ "${ORBITMESH_UPDATE_CHANNEL+x}" != x ]; then ORBITMESH_UPDATE_CHANNEL='stable'; fi
if [ "${ORBITMESH_APT_REPOSITORY_URL+x}" != x ]; then ORBITMESH_APT_REPOSITORY_URL='https://pkgs.orbitmesh.dev/edge-runtime/apt'; fi
if [ "${ORBITMESH_EDGE_UPDATE_TRUSTED_KEYS+x}" != x ]; then ORBITMESH_EDGE_UPDATE_TRUSTED_KEYS='{}'; fi


RELEASE_ID="${ORBITMESH_EDGE_RELEASE_ID:-orbitmesh}"
case "$RELEASE_ID" in ''|*[!a-z0-9-]*|-*|*-) printf 'invalid Edge release identity\n' >&2; exit 1 ;; esac
[ "${#RELEASE_ID}" -le 63 ] || exit 1
CLI_NAME="$RELEASE_ID"
DAEMON_NAME="${RELEASE_ID}d"
SERVICE_NAME="$DAEMON_NAME"
SERVICE_DESCRIPTION="OrbitMesh Edge Runtime"
if [ "$RELEASE_ID" != orbitmesh ]; then SERVICE_DESCRIPTION="$RELEASE_ID Edge Runtime"; fi
LAUNCHD_LABEL="dev.${RELEASE_ID}.${DAEMON_NAME}"
LAUNCHD_PLIST_PATH="${ORBITMESH_LAUNCHD_PLIST_PATH:-/Library/LaunchDaemons/${LAUNCHD_LABEL}.plist}"
INSTANCE_ID="${ORBITMESH_INSTANCE_ID:-orbitmesh}"
PRODUCT_NAME="${ORBITMESH_PRODUCT_NAME:-OrbitMesh}"
CONFIG_PATH="${ORBITMESH_EDGE_CONFIG:-/etc/${RELEASE_ID}/edge-runtime.yaml}"
STATE_DIR="${ORBITMESH_EDGE_STATE_DIR:-}"
RUNTIME_CONFIG_PATH="${ORBITMESH_RUNTIME_CONFIG_PATH:-}"
CONTROL_PLANE_URL="${ORBITMESH_CONTROL_PLANE_URL:-${ORBITMESH_API_URL:-https://api.agent-deploy.ai}}"
DEPLOYMENT_TOKEN="${ORBITMESH_DEPLOYMENT_TOKEN:-}"
ADAPTER="${ORBITMESH_EDGE_ADAPTER:-native}"
CLI_BIN_CONFIGURED="${ORBITMESH_CLI_BIN+x}"
DAEMON_BIN_CONFIGURED="${ORBITMESH_DAEMON_BIN+x}"
UPDATE_LAUNCHER_CONFIGURED="${ORBITMESH_UPDATE_LAUNCHER+x}"
CLI_BIN_PATH="${ORBITMESH_CLI_BIN:-/usr/local/bin/${CLI_NAME}}"
DAEMON_BIN_PATH="${ORBITMESH_DAEMON_BIN:-/usr/local/bin/${DAEMON_NAME}}"
SOCKET_PATH="${ORBITMESH_EDGE_SOCKET:-}"
CLI_LOCAL_BIN="${ORBITMESH_CLI_LOCAL_BIN:-}"
DAEMON_LOCAL_BIN="${ORBITMESH_DAEMON_LOCAL_BIN:-}"
CLI_DOWNLOAD_URL="${ORBITMESH_CLI_DOWNLOAD_URL:-}"
DAEMON_DOWNLOAD_URL="${ORBITMESH_DAEMON_DOWNLOAD_URL:-}"
DOWNLOAD_PREFIX="${ORBITMESH_EDGE_RUNTIME_DOWNLOAD_PREFIX:-https://pkgs.orbitmesh.dev/edge-runtime/latest}"
FORCE_REGISTER="${ORBITMESH_FORCE_REGISTER:-false}"
SKIP_SERVICE_MANAGER="${ORBITMESH_SKIP_SERVICE_MANAGER:-${ORBITMESH_SKIP_SYSTEMD:-false}}"
SERVICE_MANAGER="${ORBITMESH_SERVICE_MANAGER:-auto}"
ALLOW_NON_ROOT="${ORBITMESH_ALLOW_NON_ROOT:-false}"
SYSTEMD_UNIT_PATH="/etc/systemd/system/${SERVICE_NAME}.service"
PROCD_INIT_PATH="/etc/init.d/${SERVICE_NAME}"
INSTALL_COMPONENT="${ORBITMESH_INSTALL_COMPONENT:-edge-runtime}"
SERVICE_MANAGER_KIND=""
SERVICE_PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
LEGACY_STATE_DIR="/var/lib/${RELEASE_ID}/edge-runtime"
OPENWRT_STATE_DIR="/etc/${RELEASE_ID}/edge-runtime-state"
UPDATE_LAUNCHER_PATH="${ORBITMESH_UPDATE_LAUNCHER:-/usr/local/libexec/${RELEASE_ID}/edge-update-launcher}"
INSTALL_METHOD="${ORBITMESH_INSTALL_METHOD:-auto}"
OS_RELEASE_PATH="${ORBITMESH_OS_RELEASE_PATH:-/etc/os-release}"
APT_REPOSITORY_URL="${ORBITMESH_APT_REPOSITORY_URL:-https://pkgs.orbitmesh.dev/edge-runtime/apt}"
APT_KEYRING_PATH="${ORBITMESH_APT_KEYRING_PATH:-/usr/share/keyrings/${RELEASE_ID}-archive-keyring.gpg}"
APT_SOURCE_PATH="${ORBITMESH_APT_SOURCE_PATH:-/etc/apt/sources.list.d/${RELEASE_ID}-edge-runtime.list}"
DEBIAN_PACKAGE_NAME="${RELEASE_ID}-edge-runtime"
AUTO_UPDATE_CONFIGURED="${ORBITMESH_AUTO_UPDATE+x}"
UPDATE_CHANNEL_CONFIGURED="${ORBITMESH_UPDATE_CHANNEL+x}"
UPDATE_INSTALL_MODE_CONFIGURED="${ORBITMESH_UPDATE_INSTALL_MODE+x}"
UPDATE_TRUSTED_KEYS_CONFIGURED="${ORBITMESH_EDGE_UPDATE_TRUSTED_KEYS+x}"
UPDATE_BASE_URL_CONFIGURED="${ORBITMESH_UPDATE_BASE_URL+x}"
UPDATE_MANIFEST_URL_CONFIGURED="${ORBITMESH_UPDATE_MANIFEST_URL+x}"
UPDATE_SOURCE_MODE_CONFIGURED="${ORBITMESH_UPDATE_SOURCE_MODE+x}"
UPDATE_BASE_URL="${ORBITMESH_UPDATE_BASE_URL:-https://pkgs.orbitmesh.dev/edge-runtime}"
UPDATE_MANIFEST_URL="${ORBITMESH_UPDATE_MANIFEST_URL:-}"
UPDATE_SOURCE_MODE="${ORBITMESH_UPDATE_SOURCE_MODE:-shared}"
AUTO_UPDATE_ENABLED="${ORBITMESH_AUTO_UPDATE:-true}"
UPDATE_CHANNEL="${ORBITMESH_UPDATE_CHANNEL:-stable}"
UPDATE_INSTALL_MODE="${ORBITMESH_UPDATE_INSTALL_MODE:-direct}"
UPDATE_TRUSTED_KEYS="${ORBITMESH_EDGE_UPDATE_TRUSTED_KEYS:-}"
# Optional local-API access model and offline runtime artifacts. Unset keeps
# the historical behavior (root-only 0600 socket, downloads only).
LOCAL_SOCKET_GROUP="${ORBITMESH_LOCAL_SOCKET_GROUP:-}"
LOCAL_SERVICE_CALLERS="${ORBITMESH_LOCAL_SERVICE_CALLERS:-}"
SERVICE_GROUP_MEMBERS="${ORBITMESH_SERVICE_GROUP_MEMBERS:-}"
RUNTIME_LOCAL_ARTIFACT_DIR="${ORBITMESH_RUNTIME_LOCAL_ARTIFACT_DIR:-}"
# ORBITMESH_FROM_DIR points at a directory holding pre-downloaded
# orbitmesh/orbitmeshd binaries (plain or <name>-<os>-<arch> names).
FROM_DIR="${ORBITMESH_FROM_DIR:-}"
if [ -z "$UPDATE_TRUSTED_KEYS" ]; then
	UPDATE_TRUSTED_KEYS='{}'
fi

log() {
  printf '%s\n' "$*"
}

fail() {
  printf '%s install: %s\n' "$CLI_NAME" "$*" >&2
  exit 1
}

require_root() {
  if [ "$ALLOW_NON_ROOT" = "true" ]; then
    return 0
  fi
  if [ "$(id -u)" -ne 0 ]; then
    fail "run as root"
  fi
}

require_command() {
  command -v "$1" >/dev/null 2>&1 || fail "$1 is required"
}

curl_retry_connrefused_flag() {
  if curl --help all 2>/dev/null | grep -q -- '--retry-connrefused'; then
    printf '%s' '--retry-connrefused'
  fi
}

curl_retry_all_errors_flag() {
  if curl --help all 2>/dev/null | grep -q -- '--retry-all-errors'; then
    printf '%s' '--retry-all-errors'
  fi
}

curl_http1_flag() {
  if curl --help all 2>/dev/null | grep -q -- '--http1.1'; then
    printf '%s' '--http1.1'
  fi
}

detect_os() {
  os="$(uname -s | tr 'A-Z' 'a-z')"
  case "$os" in
    linux) printf 'linux' ;;
    darwin) printf 'darwin' ;;
    *) fail "unsupported OS: $os" ;;
  esac
}

detect_arch() {
  arch="$(uname -m)"
  case "$arch" in
    x86_64 | amd64) printf 'amd64' ;;
    aarch64 | arm64) printf 'arm64' ;;
    *) fail "unsupported architecture: $arch" ;;
  esac
}

artifact_download_url() {
  command_name="$1"
  explicit_url="$2"
  if [ -n "$explicit_url" ]; then
    printf '%s' "$explicit_url"
    return 0
  fi
  if [ -n "$DOWNLOAD_PREFIX" ]; then
    printf '%s/%s-%s-%s' "${DOWNLOAD_PREFIX%/}" "$command_name" "$(detect_os)" "$(detect_arch)"
    return 0
  fi
  fail "set ORBITMESH_EDGE_RUNTIME_DOWNLOAD_PREFIX or command-specific download inputs"
}

install_binary() {
  command_name="$1"
  target_path="$2"
  local_bin="$3"
  download_url="$4"

	mkdir -p "$(dirname "$target_path")"
	if [ -n "$local_bin" ]; then
		[ -f "$local_bin" ] || fail "local binary not found: $local_bin"
		install_file "$local_bin" "$target_path"
		return 0
	fi

	url="$(artifact_download_url "$command_name" "$download_url")"
	tmp="$(mktemp)"
	if ! download_file "$url" "$tmp"; then
		rm -f "$tmp"
		return 1
	fi
	install_file "$tmp" "$target_path"
	rm -f "$tmp"
}

install_file() {
	source_path="$1"
	target_path="$2"
	if command -v install >/dev/null 2>&1; then
		install -m 0755 "$source_path" "$target_path"
		return 0
	fi
	cp "$source_path" "$target_path"
	chmod 0755 "$target_path"
}

download_file() {
	download_url="$1"
	download_target_path="$2"
	if command -v curl >/dev/null 2>&1; then
		retry_connrefused="$(curl_retry_connrefused_flag)"
		retry_all_errors="$(curl_retry_all_errors_flag)"
		if curl -fsSL --connect-timeout 15 --max-time 300 \
			--retry 5 --retry-delay 2 --retry-max-time 600 \
			$retry_connrefused $retry_all_errors "$download_url" -o "$download_target_path"; then
			return 0
		fi
		http1="$(curl_http1_flag)"
		[ -n "$http1" ] || return 1
		rm -f "$download_target_path"
		log "download failed; retrying over HTTP/1.1"
		curl -fsSL --connect-timeout 15 --max-time 300 \
			--retry 5 --retry-delay 2 --retry-max-time 600 \
			$retry_connrefused $retry_all_errors $http1 "$download_url" -o "$download_target_path"
		return $?
	fi
	if command -v wget >/dev/null 2>&1; then
		wget_attempt=1
		while [ "$wget_attempt" -le 5 ]; do
			rm -f "$download_target_path"
			if wget -q -T 30 -O "$download_target_path" "$download_url"; then
				return 0
			fi
			wget_attempt=$((wget_attempt + 1))
			if [ "$wget_attempt" -le 5 ]; then
				sleep 2
			fi
		done
		return 1
	fi
	fail "curl or wget is required"
}

local_binary_from_dir() {
  command_name="$1"
  [ -n "$FROM_DIR" ] || return 0
  for candidate in \
    "$FROM_DIR/$command_name" \
    "$FROM_DIR/$command_name-$(detect_os)-$(detect_arch)"; do
    if [ -f "$candidate" ]; then
      printf '%s' "$candidate"
      return 0
    fi
  done
  fail "ORBITMESH_FROM_DIR does not contain $command_name (looked for $command_name and $command_name-$(detect_os)-$(detect_arch))"
}

sha256_file() {
 if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{print $1}'
 elif command -v shasum >/dev/null 2>&1; then shasum -a 256 "$1" | awk '{print $1}'
 elif command -v openssl >/dev/null 2>&1; then openssl dgst -sha256 "$1" | awk '{print $NF}'
 else fail "a SHA-256 utility is required"; fi
}

verify_expected_binary() {
 verify_file="$1"; verify_digest="$2"
 [ -n "$verify_digest" ] || fail "a signed branded release descriptor is required"
 [ "$(sha256_file "$verify_file")" = "$verify_digest" ] || fail "Edge artifact SHA-256 mismatch"
 chmod 0755 "$verify_file"
 [ "$("$verify_file" identity --production)" = "$RELEASE_ID" ] || fail "binary installation identity mismatch"
}

install_branded_binaries() (
 pair_work="$(mktemp -d)"
 pair_cli_pending="${CLI_BIN_PATH}.oem-pending.$$"; pair_daemon_pending="${DAEMON_BIN_PATH}.oem-pending.$$"
 pair_cli_backup="${CLI_BIN_PATH}.oem-backup.$$"; pair_daemon_backup="${DAEMON_BIN_PATH}.oem-backup.$$"
 pair_committed=0; pair_cli_replaced=0; pair_daemon_replaced=0
 pair_cleanup() {
  if [ "$pair_committed" != 1 ]; then
   if [ "$pair_cli_replaced" = 1 ]; then if [ -e "$pair_cli_backup" ] || [ -L "$pair_cli_backup" ]; then mv -f "$pair_cli_backup" "$CLI_BIN_PATH"; else rm -f "$CLI_BIN_PATH"; fi; fi
   if [ "$pair_daemon_replaced" = 1 ]; then if [ -e "$pair_daemon_backup" ] || [ -L "$pair_daemon_backup" ]; then mv -f "$pair_daemon_backup" "$DAEMON_BIN_PATH"; else rm -f "$DAEMON_BIN_PATH"; fi; fi
  fi
  rm -f "$pair_cli_pending" "$pair_daemon_pending" "$pair_cli_backup" "$pair_daemon_backup"
  rm -rf "$pair_work"
 }
 trap pair_cleanup EXIT
 trap 'exit 1' INT TERM
 [ -n "$CLI_LOCAL_BIN" ] || CLI_LOCAL_BIN="$(local_binary_from_dir "$CLI_NAME")"
 [ -n "$DAEMON_LOCAL_BIN" ] || DAEMON_LOCAL_BIN="$(local_binary_from_dir "$DAEMON_NAME")"
 if [ -n "$CLI_LOCAL_BIN" ]; then cp "$CLI_LOCAL_BIN" "$pair_work/cli"; else download_file "$(artifact_download_url "$CLI_NAME" "$CLI_DOWNLOAD_URL")" "$pair_work/cli"; fi
 if [ -n "$DAEMON_LOCAL_BIN" ]; then cp "$DAEMON_LOCAL_BIN" "$pair_work/daemon"; else download_file "$(artifact_download_url "$DAEMON_NAME" "$DAEMON_DOWNLOAD_URL")" "$pair_work/daemon"; fi
 verify_expected_binary "$pair_work/cli" "${ORBITMESH_CLI_EXPECTED_SHA256:-}"
 verify_expected_binary "$pair_work/daemon" "${ORBITMESH_DAEMON_EXPECTED_SHA256:-}"
 mkdir -p "$(dirname "$CLI_BIN_PATH")" "$(dirname "$DAEMON_BIN_PATH")"
 install_file "$pair_work/cli" "$pair_cli_pending"; install_file "$pair_work/daemon" "$pair_daemon_pending"
 if [ -e "$CLI_BIN_PATH" ] || [ -L "$CLI_BIN_PATH" ]; then cp -Pp "$CLI_BIN_PATH" "$pair_cli_backup"; fi
 if [ -e "$DAEMON_BIN_PATH" ] || [ -L "$DAEMON_BIN_PATH" ]; then cp -Pp "$DAEMON_BIN_PATH" "$pair_daemon_backup"; fi
 mv -f "$pair_cli_pending" "$CLI_BIN_PATH"; pair_cli_replaced=1
 mv -f "$pair_daemon_pending" "$DAEMON_BIN_PATH"; pair_daemon_replaced=1
 pair_committed=1
)

install_binaries() {
 if [ "$RELEASE_ID" != orbitmesh ]; then install_branded_binaries; return; fi
  [ -n "$CLI_LOCAL_BIN" ] || CLI_LOCAL_BIN="$(local_binary_from_dir "$CLI_NAME")"
  [ -n "$DAEMON_LOCAL_BIN" ] || DAEMON_LOCAL_BIN="$(local_binary_from_dir "$DAEMON_NAME")"
  install_binary "$CLI_NAME" "$CLI_BIN_PATH" "$CLI_LOCAL_BIN" "$CLI_DOWNLOAD_URL"
  install_binary "$DAEMON_NAME" "$DAEMON_BIN_PATH" "$DAEMON_LOCAL_BIN" "$DAEMON_DOWNLOAD_URL"
}

ensure_group() {
  group_name="$1"
  if getent group "$group_name" >/dev/null 2>&1; then
    return 0
  fi
  if command -v groupadd >/dev/null 2>&1; then
    groupadd --system "$group_name"
  elif command -v addgroup >/dev/null 2>&1; then
    addgroup -S "$group_name" 2>/dev/null || addgroup "$group_name"
  else
    fail "cannot create group $group_name: neither groupadd nor addgroup is available"
  fi
}

add_group_member() {
  group_name="$1"
  member="$2"
  if id -Gn "$member" 2>/dev/null | tr ' ' '\n' | grep -qx "$group_name"; then
    return 0
  fi
  if command -v usermod >/dev/null 2>&1; then
    usermod -aG "$group_name" "$member"
  elif command -v addgroup >/dev/null 2>&1; then
    addgroup "$member" "$group_name"
  else
    fail "cannot add $member to group $group_name: neither usermod nor addgroup is available"
  fi
}

configure_local_api_access() {
  if [ -n "$LOCAL_SOCKET_GROUP" ]; then
    ensure_group "$LOCAL_SOCKET_GROUP"
    set_config_value "local_api_socket_group" "$LOCAL_SOCKET_GROUP"
    old_ifs="$IFS"
    IFS=,
    for member in $SERVICE_GROUP_MEMBERS; do
      IFS="$old_ifs"
      member="$(printf '%s' "$member" | tr -d '[:space:]')"
      [ -n "$member" ] || continue
      add_group_member "$LOCAL_SOCKET_GROUP" "$member"
      log "added $member to group $LOCAL_SOCKET_GROUP"
    done
    IFS="$old_ifs"
  elif [ -n "$SERVICE_GROUP_MEMBERS" ]; then
    fail "ORBITMESH_SERVICE_GROUP_MEMBERS requires ORBITMESH_LOCAL_SOCKET_GROUP"
  fi
  if [ -n "$LOCAL_SERVICE_CALLERS" ]; then
    set_config_value "local_api_service_callers" "$LOCAL_SERVICE_CALLERS"
  fi
  if [ -n "$RUNTIME_LOCAL_ARTIFACT_DIR" ]; then
    [ -d "$RUNTIME_LOCAL_ARTIFACT_DIR" ] || fail "ORBITMESH_RUNTIME_LOCAL_ARTIFACT_DIR is not a directory: $RUNTIME_LOCAL_ARTIFACT_DIR"
    set_config_value "runtime_local_artifact_dir" "$RUNTIME_LOCAL_ARTIFACT_DIR"
  fi
}

debian_distribution_supported() {
	[ -r "$OS_RELEASE_PATH" ] || return 1
	(
		ID=""
		VERSION_ID=""
		# os-release is the distribution-provided shell-compatible identity file.
		# shellcheck source=/dev/null
		. "$OS_RELEASE_PATH"
		case "${ID:-}:${VERSION_ID:-}" in
			debian:12|debian:13|ubuntu:22.04|ubuntu:24.04|ubuntu:26.04) exit 0 ;;
			*) exit 1 ;;
		esac
	)
}

debian_package_supported() {
	debian_distribution_supported &&
		command -v apt-get >/dev/null 2>&1 &&
		command -v dpkg >/dev/null 2>&1 &&
		command -v dpkg-query >/dev/null 2>&1 &&
		command -v systemctl >/dev/null 2>&1 &&
		[ -d /run/systemd/system ]
}

resolve_install_method() {
	case "$INSTALL_METHOD" in
		auto)
			if debian_package_supported; then
				INSTALL_METHOD="apt"
			else
				INSTALL_METHOD="direct"
			fi
			;;
		apt)
			debian_package_supported || fail "APT installation requires Debian 12/13 or Ubuntu 22.04/24.04/26.04 LTS with systemd"
			;;
		direct) ;;
		*) fail "unsupported Edge Runtime install method: $INSTALL_METHOD" ;;
	esac
	if [ "$INSTALL_METHOD" = "apt" ]; then
		if [ -n "$CLI_BIN_CONFIGURED" ] && [ "$CLI_BIN_PATH" != "/usr/bin/${CLI_NAME}" ]; then
			fail "APT installation owns /usr/bin/${CLI_NAME}; custom ORBITMESH_CLI_BIN is unsupported"
		fi
		if [ -n "$DAEMON_BIN_CONFIGURED" ] && [ "$DAEMON_BIN_PATH" != "/usr/bin/${DAEMON_NAME}" ]; then
			fail "APT installation owns /usr/bin/${DAEMON_NAME}; custom ORBITMESH_DAEMON_BIN is unsupported"
		fi
		if [ -n "$UPDATE_LAUNCHER_CONFIGURED" ] && [ "$UPDATE_LAUNCHER_PATH" != "/usr/libexec/${RELEASE_ID}/edge-update-launcher" ]; then
			fail "APT installation owns the Edge Runtime update launcher path"
		fi
		CLI_BIN_PATH="/usr/bin/${CLI_NAME}"
		DAEMON_BIN_PATH="/usr/bin/${DAEMON_NAME}"
		UPDATE_LAUNCHER_PATH="/usr/libexec/${RELEASE_ID}/edge-update-launcher"
		if [ -n "$UPDATE_INSTALL_MODE_CONFIGURED" ] && [ "$UPDATE_INSTALL_MODE" != "apt" ]; then
			fail "APT installation requires ORBITMESH_UPDATE_INSTALL_MODE=apt"
		fi
		UPDATE_INSTALL_MODE="apt"
	fi
}

cache_installed_debian_package() {
	package_version="$(dpkg-query -W -f='${Version}' "$DEBIAN_PACKAGE_NAME")"
	package_arch="$(dpkg-query -W -f='${Architecture}' "$DEBIAN_PACKAGE_NAME")"
	package_filename="${DEBIAN_PACKAGE_NAME}_${package_version}_${package_arch}.deb"
	package_cache_dir="$STATE_DIR/self-update/packages"
	package_cache_path="$package_cache_dir/$package_filename"
	mkdir -p "$package_cache_dir"
	chmod 0700 "$STATE_DIR/self-update" "$package_cache_dir" 2>/dev/null || true
	if [ -f "/var/cache/apt/archives/$package_filename" ]; then
		cp "/var/cache/apt/archives/$package_filename" "$package_cache_path"
	else
		download_dir="$(mktemp -d)"
		if ! (cd "$download_dir" && apt-get download "$DEBIAN_PACKAGE_NAME=$package_version" >/dev/null); then
			rm -rf "$download_dir"
			fail "unable to cache the installed Edge Runtime package for rollback"
		fi
		set -- "$download_dir"/*.deb
		[ "$#" -eq 1 ] && [ -f "$1" ] || {
			rm -rf "$download_dir"
			fail "APT returned an unexpected Edge Runtime package set"
		}
		cp "$1" "$package_cache_path"
		rm -rf "$download_dir"
	fi
	chmod 0600 "$package_cache_path"
}

install_debian_package() {
	mkdir -p "$(dirname "$APT_KEYRING_PATH")" "$(dirname "$APT_SOURCE_PATH")"
	keyring_tmp="$(mktemp)"
	if ! download_file "${APT_REPOSITORY_URL%/}/orbitmesh-archive-keyring.gpg" "$keyring_tmp"; then
		rm -f "$keyring_tmp"
		fail "unable to download the $PRODUCT_NAME APT signing key"
	fi
	install -m 0644 "$keyring_tmp" "$APT_KEYRING_PATH"
	rm -f "$keyring_tmp"
	printf 'deb [signed-by=%s] %s %s main\n' "$APT_KEYRING_PATH" "${APT_REPOSITORY_URL%/}" "$UPDATE_CHANNEL" >"$APT_SOURCE_PATH"
	apt-get \
		-o "Dir::Etc::sourcelist=$APT_SOURCE_PATH" \
		-o "Dir::Etc::sourceparts=-" \
		-o "APT::Get::List-Cleanup=0" \
		update
 if [ "$RELEASE_ID" != orbitmesh ]; then
  [ -n "${ORBITMESH_PACKAGE_DOWNLOAD_URL:-}" ] && [ -n "${ORBITMESH_PACKAGE_EXPECTED_SHA256:-}" ] || fail "a signed Debian release descriptor is required"
  package_tmp="$(mktemp)"
  if ! download_file "$ORBITMESH_PACKAGE_DOWNLOAD_URL" "$package_tmp"; then rm -f "$package_tmp"; fail "unable to download signed package"; fi
  if [ "$(sha256_file "$package_tmp")" != "$ORBITMESH_PACKAGE_EXPECTED_SHA256" ]; then rm -f "$package_tmp"; fail "Debian package SHA-256 mismatch"; fi
  [ "$(dpkg-deb -f "$package_tmp" Package)" = "$DEBIAN_PACKAGE_NAME" ] || { rm -f "$package_tmp"; fail "Debian package identity mismatch"; }
  ORBITMESH_SELF_UPDATE=1 DEBIAN_FRONTEND=noninteractive dpkg -i "$package_tmp"
  package_version="$(dpkg-query -W -f='${Version}' "$DEBIAN_PACKAGE_NAME")"
  package_arch="$(dpkg-query -W -f='${Architecture}' "$DEBIAN_PACKAGE_NAME")"
  mkdir -p "$STATE_DIR/self-update/packages"; chmod 0700 "$STATE_DIR/self-update" "$STATE_DIR/self-update/packages"
  cp "$package_tmp" "$STATE_DIR/self-update/packages/${DEBIAN_PACKAGE_NAME}_${package_version}_${package_arch}.deb"
  rm -f "$package_tmp"
  [ "$("$CLI_BIN_PATH" identity --production)" = "$RELEASE_ID" ] && [ "$("$DAEMON_BIN_PATH" identity --production)" = "$RELEASE_ID" ] || fail "installed package binary identity mismatch"
  return
 fi
	ORBITMESH_SELF_UPDATE=1 DEBIAN_FRONTEND=noninteractive \
		apt-get install -y --no-install-recommends "$DEBIAN_PACKAGE_NAME"
	cache_installed_debian_package
}

install_edge_runtime() {
	case "$INSTALL_METHOD" in
		apt) install_debian_package ;;
		direct) install_binaries ;;
	esac
}

cli() {
  command_name="$1"
  shift
  if [ -n "$SOCKET_PATH" ]; then
    "$CLI_BIN_PATH" "$command_name" --socket "$SOCKET_PATH" "$@"
    return $?
  fi
  "$CLI_BIN_PATH" "$command_name" "$@"
}

config_has_value() {
  [ -f "$CONFIG_PATH" ] || return 1
  grep -Eq "^$1:[[:space:]]*[^[:space:]]" "$CONFIG_PATH"
}

config_value() {
  [ -f "$CONFIG_PATH" ] || return 1
  sed -n "s/^$1:[[:space:]]*//p" "$CONFIG_PATH" | sed -n '1p'
}

config_scalar() {
	scalar="$(config_value "$1" 2>/dev/null || true)"
	case "$scalar" in
		\"*\") scalar="${scalar#\"}"; scalar="${scalar%\"}" ;;
		\'*\') scalar="${scalar#\'}"; scalar="${scalar%\'}" ;;
	esac
	printf '%s' "$scalar"
}

set_config_value() {
  config_key="$1"
  config_value="$2"
  [ -f "$CONFIG_PATH" ] || return 0
  require_command awk
  tmp="$(mktemp)"
  ORBITMESH_CONFIG_WRITE_VALUE="$config_value" awk -v key="$config_key" '
BEGIN { updated = 0; value = ENVIRON["ORBITMESH_CONFIG_WRITE_VALUE"] }
$0 ~ "^[[:space:]]*" key "[[:space:]]*:" {
  print key ": " value
  updated = 1
  next
}
{ print }
END {
  if (!updated) {
    print key ": " value
  }
}' "$CONFIG_PATH" >"$tmp"
  cat "$tmp" >"$CONFIG_PATH"
  rm -f "$tmp"
  chmod 0600 "$CONFIG_PATH" 2>/dev/null || true
}

set_defaulted_config_value() {
	config_key="$1"
	config_value="$2"
	explicitly_configured="$3"
	if [ "$explicitly_configured" = "x" ] || ! config_has_value "$config_key"; then
		set_config_value "$config_key" "$config_value"
	fi
}

quoted_config_string() {
	printf '"'
	printf '%s' "$1" | sed 's/\\/\\\\/g;s/"/\\"/g'
	printf '"'
}

is_openwrt() {
	[ -x /sbin/procd ] && [ -f /etc/rc.common ]
}

resolve_state_dir() {
	if [ -n "$STATE_DIR" ]; then
		return 0
	fi
	if is_openwrt; then
		STATE_DIR="$OPENWRT_STATE_DIR"
	else
		STATE_DIR="$LEGACY_STATE_DIR"
	fi
}

migrate_openwrt_state() {
	is_openwrt || return 0
	configured_state_dir="$(config_value state_dir 2>/dev/null || true)"
	[ -n "$configured_state_dir" ] || configured_state_dir="$LEGACY_STATE_DIR"
	mkdir -p "$STATE_DIR"
	chmod 0700 "$STATE_DIR" 2>/dev/null || true
	if [ "$configured_state_dir" != "$STATE_DIR" ] && [ -d "$configured_state_dir" ] && [ ! -f "$STATE_DIR/identity.json" ]; then
		cp -a "$configured_state_dir"/. "$STATE_DIR"/
	fi
	legacy_runtime_root="$(dirname "$configured_state_dir")/runtime-instances"
	persistent_runtime_root="$(dirname "$STATE_DIR")/runtime-instances"
	if [ "$legacy_runtime_root" != "$persistent_runtime_root" ] && [ -d "$legacy_runtime_root" ] && [ ! -d "$persistent_runtime_root" ]; then
		mkdir -p "$persistent_runtime_root"
		cp -a "$legacy_runtime_root"/. "$persistent_runtime_root"/
	fi
	set_config_value "state_dir" "$STATE_DIR"
}

prepare_config_for_start() {
	mkdir -p "$(dirname "$CONFIG_PATH")"
	if [ ! -f "$CONFIG_PATH" ]; then
		: >"$CONFIG_PATH"
		chmod 0600 "$CONFIG_PATH" 2>/dev/null || true
	fi
	migrate_openwrt_state
 if [ "$RELEASE_ID" != orbitmesh ]; then set_config_value "installation_id" "$RELEASE_ID"; fi
	if [ "$INSTANCE_ID" != orbitmesh ] || [ "${ORBITMESH_INSTANCE_ID+x}" = x ]; then
		set_config_value "instance_id" "$INSTANCE_ID"
		set_config_value "product_name" "$(quoted_config_string "$PRODUCT_NAME")"
	fi
	if [ "$INSTANCE_ID" != orbitmesh ] || [ "$UPDATE_SOURCE_MODE_CONFIGURED" = x ] || config_has_value update_source_mode; then set_defaulted_config_value "update_source_mode" "$UPDATE_SOURCE_MODE" "$UPDATE_SOURCE_MODE_CONFIGURED"; fi
	if [ "$INSTANCE_ID" != orbitmesh ] || [ "$UPDATE_BASE_URL_CONFIGURED" = x ] || config_has_value update_base_url; then set_defaulted_config_value "update_base_url" "$(quoted_config_string "$UPDATE_BASE_URL")" "$UPDATE_BASE_URL_CONFIGURED"; fi
	if [ "$INSTANCE_ID" != orbitmesh ] || [ "$UPDATE_MANIFEST_URL_CONFIGURED" = x ] || config_has_value update_manifest_url; then set_defaulted_config_value "update_manifest_url" "$(quoted_config_string "$UPDATE_MANIFEST_URL")" "$UPDATE_MANIFEST_URL_CONFIGURED"; fi
	set_config_value "adapter" "$ADAPTER"
	set_defaulted_config_value "auto_update_enabled" "$AUTO_UPDATE_ENABLED" "$AUTO_UPDATE_CONFIGURED"
	set_defaulted_config_value "update_channel" "$UPDATE_CHANNEL" "$UPDATE_CHANNEL_CONFIGURED"
	if [ "$INSTALL_METHOD" = "apt" ]; then
		set_config_value "update_install_mode" "apt"
	else
		set_defaulted_config_value "update_install_mode" "$UPDATE_INSTALL_MODE" "$UPDATE_INSTALL_MODE_CONFIGURED"
	fi
	set_defaulted_config_value "update_trusted_keys" "$UPDATE_TRUSTED_KEYS" "$UPDATE_TRUSTED_KEYS_CONFIGURED"
	configure_local_api_access
}

has_registered_config() {
  config_has_value "control_plane_url" &&
    config_has_value "node_id" &&
    config_has_value "edge_runtime_id"
}

will_register() {
  [ "$FORCE_REGISTER" = "true" ] || ! has_registered_config
}

validate_registration_inputs() {
 bound_installation="$(config_scalar installation_id)"
 if [ -n "$bound_installation" ] && [ "$bound_installation" != "$RELEASE_ID" ]; then fail "this configuration belongs to another Edge release; use the explicit migration procedure"; fi

	bound_instance="$(config_scalar instance_id)"
	if [ -n "$bound_instance" ] && [ "$bound_instance" != "$INSTANCE_ID" ]; then
		fail "this configuration belongs to another instance; use a separate configuration and state directory"
	fi
	if [ -z "$bound_instance" ] && [ "$INSTANCE_ID" != orbitmesh ] && has_registered_config; then
		registered_api="$(config_scalar control_plane_url | sed 's#/*$##')"
		requested_api="$(printf '%s' "$CONTROL_PLANE_URL" | sed 's#/*$##')"
		[ "$registered_api" = "$requested_api" ] || fail "this registered configuration belongs to another API; use a separate configuration and state directory"
	fi
	case "$UPDATE_SOURCE_MODE" in shared|custom) ;; *) fail "unsupported update source mode" ;; esac
	if [ "$UPDATE_SOURCE_MODE" = custom ]; then
		[ -n "${ORBITMESH_UPDATE_BASE_URL:-}" ] || fail "custom updates require an explicit update base URL"
		[ -n "${ORBITMESH_EDGE_RUNTIME_DOWNLOAD_PREFIX:-}" ] || fail "custom installation requires an explicit binary download prefix"
		[ -n "${ORBITMESH_APT_REPOSITORY_URL:-}" ] || fail "custom installation requires an explicit APT repository URL"
	fi
	if [ "$UPDATE_SOURCE_MODE" = custom ] && { [ -z "$UPDATE_BASE_URL" ] || [ "$UPDATE_TRUSTED_KEYS" = '{}' ]; }; then
		fail "custom updates require an explicit update base URL and trusted signing keys"
	fi
	case "$AUTO_UPDATE_ENABLED" in
		true|false) ;;
		*) fail "ORBITMESH_AUTO_UPDATE must be true or false" ;;
	esac
	case "$UPDATE_CHANNEL" in
		stable|candidate|unstable) ;;
		*) fail "unsupported Edge Runtime update channel: $UPDATE_CHANNEL" ;;
	esac
	case "$UPDATE_INSTALL_MODE" in
		direct|standalone|apt) ;;
		*) fail "unsupported Edge Runtime update install mode: $UPDATE_INSTALL_MODE" ;;
	esac
  if will_register; then
    [ -n "$CONTROL_PLANE_URL" ] || fail "ORBITMESH_CONTROL_PLANE_URL is required"
    [ -n "$DEPLOYMENT_TOKEN" ] || fail "ORBITMESH_DEPLOYMENT_TOKEN is required"
  fi
}

detect_service_manager() {
	if [ "$SKIP_SERVICE_MANAGER" = "true" ]; then
		printf 'none'
		return 0
	fi
	case "$SERVICE_MANAGER" in
		systemd)
			command -v systemctl >/dev/null 2>&1 || fail "systemctl is required"
			printf 'systemd'
			return 0
			;;
		procd)
			[ -x /sbin/procd ] && [ -f /etc/rc.common ] || fail "procd is required"
			printf 'procd'
			return 0
			;;
        launchd)
            [ "$(detect_os)" = darwin ] && command -v launchctl >/dev/null 2>&1 || fail "launchd is required"
            printf 'launchd'; return 0 ;;
		auto) ;;
		*) fail "unsupported service manager: $SERVICE_MANAGER" ;;
	esac
	if command -v systemctl >/dev/null 2>&1 && [ -d /run/systemd/system ]; then
		printf 'systemd'
		return 0
	fi
	if [ -x /sbin/procd ] && [ -f /etc/rc.common ]; then
		printf 'procd'
		return 0
	fi
    if [ "$(detect_os)" = darwin ] && command -v launchctl >/dev/null 2>&1; then printf 'launchd'; return 0; fi
	fail "no supported service manager found"
}

write_systemd_unit() {

  daemon_socket_args=""
  if [ -n "$SOCKET_PATH" ]; then
    daemon_socket_args=" --socket ${SOCKET_PATH}"
  fi

  cat >"$SYSTEMD_UNIT_PATH" <<EOF
# Edge release: ${RELEASE_ID}
[Unit]
Description=${SERVICE_DESCRIPTION}
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=${UPDATE_LAUNCHER_PATH} ${STATE_DIR} ${DAEMON_BIN_PATH} --config ${CONFIG_PATH}${daemon_socket_args}
Restart=always
RestartSec=5
User=root
Group=root
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target
EOF
}

write_update_launcher() {
	mkdir -p "$(dirname "$UPDATE_LAUNCHER_PATH")"
	cat >"$UPDATE_LAUNCHER_PATH" <<'EOF'
#!/bin/sh
set -eu

state_dir="$1"
shift
active="${state_dir%/}/self-update/active"
if [ -d "$active" ]; then
	attempts_file="$active/attempts"
	attempts="$(cat "$attempts_file" 2>/dev/null || printf '0')"
	case "$attempts" in
		''|*[!0-9]*) attempts=0 ;;
	esac
	attempts=$((attempts + 1))
	printf '%s\n' "$attempts" >"$attempts_file"
	if [ "$attempts" -gt 3 ]; then
		/bin/sh "$active/rollback.sh"
	fi
fi
exec "$@"
EOF
	chmod 0755 "$UPDATE_LAUNCHER_PATH"
}

write_procd_service() {
	if [ -n "$SOCKET_PATH" ]; then
		cat >"$PROCD_INIT_PATH" <<EOF
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=95
STOP=10

start_service() {
	procd_open_instance
	procd_set_param command "$UPDATE_LAUNCHER_PATH" "$STATE_DIR" "$DAEMON_BIN_PATH" --config "$CONFIG_PATH" --socket "$SOCKET_PATH"
	procd_set_param env PATH="$SERVICE_PATH"
	procd_set_param respawn 3600 5 5
	procd_set_param stdout 1
	procd_set_param stderr 1
	procd_close_instance
}
EOF
	else
		cat >"$PROCD_INIT_PATH" <<EOF
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=95
STOP=10

start_service() {
	procd_open_instance
	procd_set_param command "$UPDATE_LAUNCHER_PATH" "$STATE_DIR" "$DAEMON_BIN_PATH" --config "$CONFIG_PATH"
	procd_set_param env PATH="$SERVICE_PATH"
	procd_set_param respawn 3600 5 5
	procd_set_param stdout 1
	procd_set_param stderr 1
	procd_close_instance
}
EOF
	fi
	chmod 0755 "$PROCD_INIT_PATH"
}

xml_escape() {
 printf '%s' "$1" | sed -e 's/\&/\&amp;/g' -e 's/</\&lt;/g' -e 's/>/\&gt;/g' -e 's/"/\&quot;/g'
}

write_launchd_service() {
 mkdir -p "$(dirname "$LAUNCHD_PLIST_PATH")" "/var/log/$RELEASE_ID"
 {
  printf '%s\n' '<?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>'
  printf '<key>Label</key><string>%s</string>\n' "$(xml_escape "$LAUNCHD_LABEL")"
  printf '%s\n' '<key>ProgramArguments</key><array>'
  for argument in "$UPDATE_LAUNCHER_PATH" "$STATE_DIR" "$DAEMON_BIN_PATH" --config "$CONFIG_PATH"; do printf '<string>%s</string>\n' "$(xml_escape "$argument")"; done
  if [ -n "$SOCKET_PATH" ]; then printf '<string>--socket</string><string>%s</string>\n' "$(xml_escape "$SOCKET_PATH")"; fi
  printf '%s\n' '</array>' '<key>RunAtLoad</key><true/>' '<key>KeepAlive</key><true/>' '<key>ProcessType</key><string>Background</string>'
  printf '<key>StandardOutPath</key><string>/var/log/%s/edge-runtime.log</string>\n' "$RELEASE_ID"
  printf '<key>StandardErrorPath</key><string>/var/log/%s/edge-runtime-error.log</string>\n' "$RELEASE_ID"
  printf '%s\n' '</dict></plist>'
 } > "$LAUNCHD_PLIST_PATH"
 chmod 0644 "$LAUNCHD_PLIST_PATH"
}

write_service_definition() {
	if [ "$INSTALL_METHOD" = "apt" ]; then
		SERVICE_MANAGER_KIND="systemd"
		if [ -f "$SYSTEMD_UNIT_PATH" ] && { grep -Fq "# Edge release: $RELEASE_ID" "$SYSTEMD_UNIT_PATH" || { [ "$RELEASE_ID" = orbitmesh ] && grep -q "OrbitMesh Edge Runtime" "$SYSTEMD_UNIT_PATH"; }; }; then
			rm -f "$SYSTEMD_UNIT_PATH"
		fi
		return 0
	fi
	SERVICE_MANAGER_KIND="$(detect_service_manager)"
	case "$SERVICE_MANAGER_KIND" in
		systemd) write_systemd_unit ;;
		procd) write_procd_service ;;
        launchd) write_launchd_service ;;
		none) log "service manager setup skipped" ;;
	esac
}

register_node() {
  if [ "$FORCE_REGISTER" != "true" ] && has_registered_config; then
    log "existing edge runtime config found; skip registration"
    return 0
  fi

  [ -n "$CONTROL_PLANE_URL" ] || fail "ORBITMESH_CONTROL_PLANE_URL is required"
  [ -n "$DEPLOYMENT_TOKEN" ] || fail "ORBITMESH_DEPLOYMENT_TOKEN is required"

  wait_for_daemon
  mkdir -p "$(dirname "$CONFIG_PATH")" "$STATE_DIR"
  if [ -n "$RUNTIME_CONFIG_PATH" ]; then
    mkdir -p "$(dirname "$RUNTIME_CONFIG_PATH")"
  fi
  cli up \
    --control-plane-url "$CONTROL_PLANE_URL" \
    --deployment-token "$DEPLOYMENT_TOKEN" \
    --adapter "$ADAPTER" \
    --state-dir "$STATE_DIR" \
    --runtime-config-path "$RUNTIME_CONFIG_PATH"
}

verify_existing_node() {
  wait_for_daemon
  cli status >/dev/null
  log "existing edge runtime config found; preserve operator state"
}

start_daemon_service() {
	case "$SERVICE_MANAGER_KIND" in
		systemd)
			systemctl daemon-reload
			systemctl enable "$SERVICE_NAME"
			systemctl restart "$SERVICE_NAME"
			systemctl --no-pager --full status "$SERVICE_NAME" >/dev/null 2>&1 || fail "service failed to start"
			;;
		procd)
			"$PROCD_INIT_PATH" enable
			if "$PROCD_INIT_PATH" running >/dev/null 2>&1; then
				"$PROCD_INIT_PATH" restart
			else
				"$PROCD_INIT_PATH" start
			fi
			"$PROCD_INIT_PATH" running >/dev/null 2>&1 || fail "service failed to start"
			;;
        launchd)
            launchctl bootout system "$LAUNCHD_PLIST_PATH" >/dev/null 2>&1 || true
            launchctl bootstrap system "$LAUNCHD_PLIST_PATH"
            launchctl enable "system/$LAUNCHD_LABEL"
            launchctl kickstart -k "system/$LAUNCHD_LABEL"
            ;;
		none) ;;
	esac
}

wait_for_daemon() {
  attempts=0
  while [ "$attempts" -lt 30 ]; do
    if cli status >/dev/null 2>&1; then
      return 0
    fi
    attempts=$((attempts + 1))
    sleep 1
  done
  fail "$DAEMON_NAME local API is not ready"
}

main() {
  [ "$INSTALL_COMPONENT" = "edge-runtime" ] || fail "unsupported install component: $INSTALL_COMPONENT"
	require_root
	resolve_state_dir
	resolve_install_method
  validate_registration_inputs
	install_edge_runtime
	prepare_config_for_start
	if [ "$INSTALL_METHOD" != "apt" ]; then
		write_update_launcher
	fi
	write_service_definition
	start_daemon_service
	if will_register; then
		register_node
	else
		verify_existing_node
	fi
  log "$PRODUCT_NAME edge runtime installed"
}

main "$@"
