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

### --- OS CHECK --- ###
if [[ $OSTYPE != linux-gnu* ]]; then
  echo "[ERROR] This script supports Linux only. Aborting."
  exit 1
fi

# --- Auto-save if running from a pipe ---
if [ -p /dev/stdin ]; then
  TMP_SCRIPT="/tmp/install-edge.sh"
  echo "[INFO] Detected script running from a pipe. Saving to $TMP_SCRIPT..."
  cat >"$TMP_SCRIPT"
  chmod +x "$TMP_SCRIPT"

  echo "[INFO] Re-running saved script..."
  exec /usr/bin/env bash "$TMP_SCRIPT" "$@"
fi

### --- CONFIGURATION --- ###
IMAGE_NAME="ghcr.io/autonomy-logic/orchestrator-agent:latest"
NETMON_IMAGE_NAME="ghcr.io/autonomy-logic/autonomy-netmon:latest"
CONTAINER_NAME="orchestrator_agent"
NETMON_CONTAINER_NAME="autonomy_netmon"
SOURCE_DIR="/tmp/orchestrator-agent"
SHARED_VOLUME="orchestrator-shared"
SERVER_DNS="api.autonomylogic.com"
SERVER_URL="https://$SERVER_DNS"
GET_ID_URL="$SERVER_URL/orchestrators/id"
ENROLL_URL="$SERVER_URL/orchestrators/enroll"
MTLS_DIR="$HOME/.mtls"
KEY_PATH="$MTLS_DIR/client.key"
CRT_PATH="$MTLS_DIR/client.crt"
CSR_PATH="$MTLS_DIR/client.csr"
CSR_CONFIG_FILE="$MTLS_DIR/client.conf"
POLL_INTERVAL_SECONDS=3

# mktemp the response files so a malicious local user can't pre-create them as
# symlinks before sudo elevates this script.
ENROLL_RESP_FILE=$(mktemp -t orchestrator-enroll-resp.XXXXXX)
PENDING_RESP_FILE=$(mktemp -t orchestrator-pending-resp.XXXXXX)

# When true, the EXIT trap will remove the freshly-generated mTLS material.
# Set to true after we create $MTLS_DIR; cleared once validation succeeds, so a
# script that aborts before validation does not leave a dead identity behind.
CLEANUP_CERTS_ON_FAILURE=false

# Cleanup function for trap - ensures temp files are removed on exit and
# (when applicable) drops the unvalidated mTLS material.
cleanup_temp_files() {
  rm -f "${CSR_PATH:-}" "${CSR_CONFIG_FILE:-}" \
    "${ENROLL_RESP_FILE:-}" "${PENDING_RESP_FILE:-}" 2>/dev/null || true

  if [ "$CLEANUP_CERTS_ON_FAILURE" = true ]; then
    echo "[INFO] Removing unvalidated mTLS material from $MTLS_DIR"
    rm -f "$KEY_PATH" "$CRT_PATH" 2>/dev/null || true
    # Non-recursive on purpose: if the user has unrelated files in ~/.mtls we
    # leave them alone. Do NOT change this to rm -rf.
    rmdir "$MTLS_DIR" 2>/dev/null || true
  fi
}
trap cleanup_temp_files EXIT

# Check for root privileges
check_root() {
  if [[ $EUID -ne 0 ]]; then
    echo "[INFO] Root privileges are required. Trying to elevate with sudo..."
    # Re-run the script with sudo, passing all original arguments
    exec sudo /usr/bin/env bash "$0" "$@"
    # exec replaces the current shell with the new command, so the rest of the script continues as root
  fi
}

# Make sure we are root before proceeding
check_root "$@"

### --- DEPENDENCIES --- ###
echo "Checking and installing required dependencies..."
PKG_MANAGER=""

# Detect package manager
if command -v apt-get &>/dev/null; then
  PKG_MANAGER="apt-get"
elif command -v dnf &>/dev/null; then
  PKG_MANAGER="dnf"
elif command -v yum &>/dev/null; then
  PKG_MANAGER="yum"
else
  echo "[ERROR] No supported package manager found (apt, dnf, or yum). Install dependencies manually."
  echo "Required packages: curl, jq, openssl, docker"
  echo "Attempting to continue without automatic dependency installation..."
  PKG_MANAGER="none"
fi

# Define package names per package manager
declare -A PKG_MAP
if [[ "$PKG_MANAGER" == "apt-get" ]]; then
  PKG_MAP=(
    [curl]="curl"
    [jq]="jq"
    [openssl]="openssl"
    [docker]="docker.io"
  )
elif [[ "$PKG_MANAGER" == "dnf" ]]; then
  PKG_MAP=(
    [curl]="curl"
    [jq]="jq"
    [openssl]="openssl"
    [docker]="docker"
  )
elif [[ "$PKG_MANAGER" == "yum" ]]; then
  PKG_MAP=(
    [curl]="curl"
    [jq]="jq"
    [openssl]="openssl"
    [docker]="docker"
  )
fi

# Collect missing packages
MISSING_PKGS=()
for cmd in curl jq openssl docker; do
  if ! command -v "$cmd" &>/dev/null; then
    echo "Missing dependency: $cmd"
    if [[ -n "${PKG_MAP[$cmd]}" ]]; then
      MISSING_PKGS+=("${PKG_MAP[$cmd]}")
    fi
  else
    echo "[SUCCESS] $cmd is already installed."
  fi
done

# Install missing packages
if [ ${#MISSING_PKGS[@]} -ne 0 ]; then
  echo "Updating package lists and installing missing dependencies: ${MISSING_PKGS[*]}"
  case "$PKG_MANAGER" in
  apt-get)
    sudo apt-get update -y
    sudo apt-get install -y "${MISSING_PKGS[@]}"
    ;;
  dnf)
    sudo dnf install -y "${MISSING_PKGS[@]}"
    ;;
  yum)
    sudo yum install -y "${MISSING_PKGS[@]}"
    ;;
  none)
    echo "[ERROR] Cannot install dependencies automatically. Please install: ${MISSING_PKGS[*]}"
    exit 1
    ;;
  esac
fi

### --- COLOR DETECTION --- ###
if [ -t 1 ] && command -v tput >/dev/null && [ "$(tput colors 2>/dev/null)" -ge 8 ]; then
  GREEN="$(tput setaf 2)"
  CYAN="$(tput setaf 6)"
  YELLOW="$(tput setaf 3)"
  RED="$(tput setaf 1)"
  GRAY="$(tput setaf 8)"
  BOLD="$(tput bold)"
  RESET="$(tput sgr0)"
else
  GREEN=""
  CYAN=""
  YELLOW=""
  RED=""
  GRAY=""
  BOLD=""
  RESET=""
fi

echo "Creating shared volume for container communication..."
if docker volume inspect "$SHARED_VOLUME" &>/dev/null; then
  echo "[SUCCESS] Shared volume $SHARED_VOLUME already exists"
else
  docker volume create "$SHARED_VOLUME"
  echo "[SUCCESS] Created shared volume $SHARED_VOLUME"
fi

### --- UPGRADE DETECTION --- ###
# If an orchestrator is already running with valid mTLS certs, perform an
# in-place upgrade instead of a full install. This preserves the existing
# identity, certificates, vPLC containers, and network configuration.
EXISTING_ORCHESTRATOR=false
if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
  EXISTING_MTLS_DIR=$(docker inspect "$CONTAINER_NAME" --format '{{range .Mounts}}{{if eq .Destination "/root/.mtls"}}{{.Source}}{{end}}{{end}}' 2>/dev/null || true)
  if [ -n "$EXISTING_MTLS_DIR" ] && [ -f "$EXISTING_MTLS_DIR/client.crt" ] && [ -f "$EXISTING_MTLS_DIR/client.key" ]; then
    EXISTING_ORCHESTRATOR=true
  fi
fi

if [ "$EXISTING_ORCHESTRATOR" = true ]; then
  echo ""
  echo "======================================================"
  echo "  EXISTING ORCHESTRATOR DETECTED — UPGRADING IN-PLACE"
  echo "======================================================"
  echo ""
  echo "mTLS certificates: $EXISTING_MTLS_DIR"
  echo "Shared volume: $SHARED_VOLUME"
  echo ""

  # Pull latest images
  echo "Pulling latest orchestrator image..."
  docker pull "$IMAGE_NAME"
  echo "Pulling latest netmon image..."
  docker pull "$NETMON_IMAGE_NAME"

  # Upgrade netmon sidecar
  echo "Upgrading network monitor sidecar..."
  if docker ps -a --format '{{.Names}}' | grep -q "^${NETMON_CONTAINER_NAME}$"; then
    docker rm -f "$NETMON_CONTAINER_NAME"
  fi
  docker run -d \
    --name "$NETMON_CONTAINER_NAME" \
    --network=host \
    --pid=host \
    --privileged \
    --restart unless-stopped \
    -v "$SHARED_VOLUME:/var/orchestrator" \
    -v /dev:/dev \
    -v /run/udev:/run/udev:ro \
    "$NETMON_IMAGE_NAME"
  echo "[SUCCESS] Network monitor sidecar upgraded"

  # Clean up any leftover upgrader from a previous attempt
  docker rm -f orchestrator_upgrader 2>/dev/null || true

  # Record the old container ID so we can detect when it's been replaced
  OLD_CONTAINER_ID=$(docker inspect "$CONTAINER_NAME" --format '{{.Id}}' 2>/dev/null || true)
  echo "Old orchestrator container: ${OLD_CONTAINER_ID:0:12}"

  # Spawn the upgrader container — same process as the v1.0.0+ remote upgrade.
  echo "Spawning upgrader container..."
  docker run -d \
    --name orchestrator_upgrader \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -e UPGRADE_MODE=true \
    -e TARGET_CONTAINER="$CONTAINER_NAME" \
    -e NEW_IMAGE="$IMAGE_NAME" \
    -e MTLS_HOST_PATH="$EXISTING_MTLS_DIR" \
    -e SHARED_VOLUME="$SHARED_VOLUME" \
    "$IMAGE_NAME" \
    python src/tools/upgrade_self.py

  # Step 1: Wait for old orchestrator to be stopped and removed
  echo "Waiting for old orchestrator to be removed..."
  for i in $(seq 1 30); do
    CURRENT_ID=$(docker inspect "$CONTAINER_NAME" --format '{{.Id}}' 2>/dev/null || true)
    if [ -z "$CURRENT_ID" ] || [ "$CURRENT_ID" != "$OLD_CONTAINER_ID" ]; then
      echo "[OK] Old orchestrator removed"
      break
    fi
    sleep 1
  done

  # Step 2: Wait for new orchestrator container to appear and be running
  echo "Waiting for new orchestrator to start..."
  UPGRADE_OK=false
  for i in $(seq 1 30); do
    NEW_ID=$(docker inspect "$CONTAINER_NAME" --format '{{.Id}}' 2>/dev/null || true)
    if [ -n "$NEW_ID" ] && [ "$NEW_ID" != "$OLD_CONTAINER_ID" ]; then
      NEW_STATUS=$(docker inspect "$CONTAINER_NAME" --format '{{.State.Status}}' 2>/dev/null || true)
      if [ "$NEW_STATUS" = "running" ]; then
        echo "[OK] New orchestrator running: ${NEW_ID:0:12}"
        UPGRADE_OK=true
        break
      fi
    fi
    sleep 1
  done

  if [ "$UPGRADE_OK" != "true" ]; then
    echo "[ERROR] Upgrade failed. Check logs with: docker logs orchestrator_upgrader"
    exit 1
  fi

  echo ""
  echo "======================================================"
  echo "  UPGRADE COMPLETE"
  echo "======================================================"
  echo ""
  echo "The orchestrator has been upgraded to the latest version."
  echo "All vPLC containers and configurations have been preserved."
  echo ""
  exit 0
fi

### --- STEP 1: REQUEST CUSTOM ID --- ###
echo "Requesting ID from $GET_ID_URL..."
response=$(curl -fsSL "$GET_ID_URL")

# Validate JSON format
if ! echo "$response" | jq empty 2>/dev/null; then
  echo "[ERROR] Invalid server response: not JSON."
  echo "$response"
  exit 1
fi

CUSTOM_ID=$(echo "$response" | jq -r '.data.id')
EXPIRES_AT=$(echo "$response" | jq -r '.data.expiresAt')
EXPIRES_IN=$(echo "$response" | jq -r '.data.expiresIn')

if [[ -z "$CUSTOM_ID" || "$CUSTOM_ID" == "null" ]]; then
  echo "[ERROR] Failed to retrieve ID from server."
  exit 1
fi

# Sanitize EXPIRES_IN — fall back to 300s if the server omits it.
if ! [[ "$EXPIRES_IN" =~ ^[0-9]+$ ]] || [ "$EXPIRES_IN" -lt 30 ]; then
  EXPIRES_IN=300
fi

PENDING_URL="$SERVER_URL/orchestrators/$CUSTOM_ID/pending"

### --- STEP 2: GENERATE CLIENT KEY AND CSR --- ###
echo "Generating client key and certificate signing request..."
mkdir -p "$MTLS_DIR"
chmod 700 "$MTLS_DIR"
# From this point on, any failure before validation should leave the host clean.
CLEANUP_CERTS_ON_FAILURE=true

echo ""
echo "Generating client certificate for orchestrator ID: $CUSTOM_ID"
echo ""

# STEP 2.1: Generate client private key
echo "--- 1. Generating client private key ---"
if ! openssl genrsa -out "$KEY_PATH" 4096 2>/dev/null; then
  echo "[ERROR] Failed to generate client private key. Aborting."
  exit 1
fi
chmod 600 "$KEY_PATH"
echo "Client private key generated: $KEY_PATH"

# STEP 2.2: Create CSR configuration file
echo "--- 2. Creating CSR configuration ---"
cat <<EOF > "$CSR_CONFIG_FILE"
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[req_distinguished_name]
C=BR
ST=SP
L=SaoPaulo
O=AutonomyLogic
OU=Production
CN=${CUSTOM_ID}

[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = clientAuth
EOF

echo "CSR configuration created"

# STEP 2.3: Generate CSR (Certificate Signing Request)
echo "--- 3. Generating Certificate Signing Request (CSR) ---"
openssl req -new \
  -key "$KEY_PATH" \
  -out "$CSR_PATH" \
  -config "$CSR_CONFIG_FILE" 2>/dev/null

echo "CSR generated: $CSR_PATH"

### --- STEP 3: ENROLL WITH SERVER (CSR SIGNING) --- ###
echo "--- 4. Submitting CSR to server for signing ---"
echo "Enrolling with $ENROLL_URL..."
http_code=$(curl -sS -w "%{http_code}" -o "$ENROLL_RESP_FILE" \
  -X POST "$ENROLL_URL" \
  -F "csr=@$CSR_PATH") || {
  echo "[ERROR] Enrollment request failed. Please check network connectivity."
  exit 1
}

if [[ -z "$http_code" || ! "$http_code" =~ ^[0-9]{3}$ ]]; then
  echo "[ERROR] Invalid HTTP response code received: $http_code"
  exit 1
fi

if [[ "$http_code" -ne 200 ]]; then
  echo "[ERROR] Enrollment failed. HTTP code: $http_code"
  echo "Server response:"
  cat "$ENROLL_RESP_FILE"
  echo
  exit 1
fi

# Extract certificate from response JSON
certificate=$(jq -r '.data.certificate' "$ENROLL_RESP_FILE")
message=$(jq -r '.data.message' "$ENROLL_RESP_FILE")
id_resp=$(jq -r '.data.id' "$ENROLL_RESP_FILE")
status=$(jq -r '.statusCode' "$ENROLL_RESP_FILE")

if [[ "$status" != "200" ]]; then
  echo "[WARNING] Unexpected server status: $status"
  cat "$ENROLL_RESP_FILE"
  echo
  exit 1
fi

if [[ -z "$certificate" || "$certificate" == "null" ]]; then
  echo "[ERROR] No certificate received from server"
  cat "$ENROLL_RESP_FILE"
  echo
  exit 1
fi

# Save the signed certificate
echo "$certificate" > "$CRT_PATH"
chmod 644 "$CRT_PATH"
echo "Client certificate signed and saved: $CRT_PATH"

# Verify the certificate has correct extensions for mTLS client auth
echo "--- 5. Verifying certificate extensions ---"
if ! openssl x509 -in "$CRT_PATH" -noout -purpose 2>/dev/null | grep -q "SSL client : Yes"; then
  echo "[ERROR] Server returned a certificate that is not valid for SSL client authentication."
  echo "This may indicate a server misconfiguration. Please contact support."
  exit 1
fi
echo "Certificate verified: valid for SSL client authentication"

echo ""
echo "CERTIFICATE ENROLLMENT COMPLETE"
echo "=================================================="
echo "Files created:"
echo "   - Client key:         $KEY_PATH"
echo "   - Client certificate: $CRT_PATH"
echo ""
echo "   Valid until:"
openssl x509 -in "$CRT_PATH" -noout -enddate
echo ""
echo "   Fingerprint SHA256:"
openssl x509 -in "$CRT_PATH" -noout -fingerprint -sha256
echo ""
echo "=================================================="
echo ""
echo "[SUCCESS] Enrollment completed: $message (ID: $id_resp)"

### --- STEP 4: WAIT FOR USER VALIDATION ON AUTONOMY EDGE --- ###
echo
echo -e "${BOLD}${GREEN}=====================================================${RESET}"
echo -e "${BOLD}${GREEN}  ACTION REQUIRED: VALIDATE YOUR ORCHESTRATOR ID     ${RESET}"
echo -e "${BOLD}${GREEN}=====================================================${RESET}"
echo
echo -e "Orchestrator ID: ${BOLD}${CYAN}${CUSTOM_ID}${RESET}"
echo
echo "Open the Autonomy Edge application and link a new orchestrator"
echo "using the ID above. The installation will continue automatically"
echo "as soon as the validation is recorded."
echo
echo -e "${GRAY}If the ID is not validated within ${EXPIRES_IN}s, the installation${RESET}"
echo -e "${GRAY}will be aborted and the unvalidated certificate removed.${RESET}"
echo

START_TS=$(date +%s)
USE_CR=false
[ -t 1 ] && USE_CR=true

VALIDATED=false
FAIL_REASON=""
TRANSIENT_WARN_PRINTED=false

while :; do
  ELAPSED=$(( $(date +%s) - START_TS ))
  REMAINING=$(( EXPIRES_IN - ELAPSED ))
  if [ "$REMAINING" -le 0 ]; then
    FAIL_REASON="timeout"
    break
  fi

  poll_code=$(curl -sS -o "$PENDING_RESP_FILE" -w "%{http_code}" "$PENDING_URL" 2>/dev/null || echo "000")

  if [ "$poll_code" = "200" ]; then
    poll_status=$(jq -r '.data.status // .status // empty' "$PENDING_RESP_FILE" 2>/dev/null || echo "")
    if [ "$poll_status" = "validated" ]; then
      VALIDATED=true
      break
    fi
  elif [ "$poll_code" = "404" ]; then
    FAIL_REASON="server-rejected"
    break
  else
    # 000 timeout, 5xx, etc. — keep polling, but surface a one-shot warning so
    # a permanently-unhealthy server doesn't look like a silent countdown.
    if [ "$TRANSIENT_WARN_PRINTED" = false ]; then
      if [ "$USE_CR" = true ]; then printf "\r\033[K"; fi
      echo -e "${YELLOW}[WARN] Server returned ${poll_code} while polling for validation; will keep retrying.${RESET}"
      TRANSIENT_WARN_PRINTED=true
    fi
  fi

  if [ "$USE_CR" = true ]; then
    printf "\r${YELLOW}Waiting for validation… %3ds remaining${RESET}\033[K" "$REMAINING"
  elif (( REMAINING % 30 == 0 )) || [ "$REMAINING" -le 10 ]; then
    echo "Waiting for validation… ${REMAINING}s remaining"
  fi

  sleep "$POLL_INTERVAL_SECONDS"
done

if [ "$USE_CR" = true ]; then printf "\r\033[K"; fi

if [ "$VALIDATED" != true ]; then
  echo
  if [ "$FAIL_REASON" = "server-rejected" ]; then
    echo -e "${BOLD}${RED}Server reports the orchestrator ID is unknown or expired.${RESET}"
    echo -e "${YELLOW}Reverting: removing the unvalidated certificate. No containers were created.${RESET}"
    echo "Re-run the installer to request a fresh ID and try again."
  else
    echo -e "${BOLD}${YELLOW}Installation was not validated on Autonomy Edge.${RESET}"
    echo -e "${YELLOW}Reverting: removing the unvalidated certificate. No containers were created.${RESET}"
    echo "Re-run the installer and complete the validation in the app to finish setup."
  fi
  exit 1
fi

# Validation succeeded — keep the cert files past the trap.
CLEANUP_CERTS_ON_FAILURE=false
echo
echo -e "${BOLD}${GREEN}Validation confirmed. Continuing installation…${RESET}"
echo

### --- STEP 5: DEPLOY NETWORK MONITOR SIDECAR --- ###
echo "Deploying network monitor sidecar container..."

if docker pull "$NETMON_IMAGE_NAME" 2>/dev/null; then
  echo "[SUCCESS] Pulled network monitor image: $NETMON_IMAGE_NAME"
else
  echo "[WARNING] No prebuilt netmon image found. Falling back to local build..."

  if [ -d "$SOURCE_DIR/.git" ]; then
    echo "Updating existing source clone..."
    if ! git -C "$SOURCE_DIR" pull --rebase; then
      echo "Pull failed, stashing local changes and retrying..."
      git -C "$SOURCE_DIR" stash push --include-untracked -m "installer-auto-stash $(date +%s)" || true
      if ! git -C "$SOURCE_DIR" pull --rebase; then
        echo "[ERROR] git pull still failing after stash. Please inspect $SOURCE_DIR."
        exit 1
      fi
    fi
  else
    echo "Cloning source to $SOURCE_DIR..."
    git clone https://github.com/autonomy-logic/orchestrator-agent.git "$SOURCE_DIR"
  fi

  echo "Building network monitor image locally..."
  docker build -t "$NETMON_IMAGE_NAME" -f "$SOURCE_DIR/install/Dockerfile.netmon" "$SOURCE_DIR/install"

  echo "[SUCCESS] Local netmon build completed: $NETMON_IMAGE_NAME"
fi

if docker ps -a --format '{{.Names}}' | grep -q "^${NETMON_CONTAINER_NAME}$"; then
  echo "Removing existing network monitor container..."
  docker rm -f "$NETMON_CONTAINER_NAME"
fi


docker run -d \
  --name "$NETMON_CONTAINER_NAME" \
  --network=host \
  --pid=host \
  --privileged \
  --restart unless-stopped \
  -v "$SHARED_VOLUME:/var/orchestrator" \
  -v /dev:/dev \
  -v /run/udev:/run/udev:ro \
  "$NETMON_IMAGE_NAME"

echo "[SUCCESS] Network monitor sidecar started"

### --- STEP 6: PULL ORCHESTRATOR AGENT IMAGE AND CREATE CONTAINER --- ###
echo "Pulling Docker image: $IMAGE_NAME"
if docker pull "$IMAGE_NAME"; then
  echo "Pulled image: $IMAGE_NAME"
else
  echo "[WARNING] No prebuilt image found for this host architecture. Falling back to local build..."
  # Clone or update the source tree
  if [ -d "$SOURCE_DIR/.git" ]; then
    echo "Updating existing source clone..."
    if ! git -C "$SOURCE_DIR" pull --rebase; then
      echo "Pull failed, stashing local changes and retrying..."
      git -C "$SOURCE_DIR" stash push --include-untracked -m "installer-auto-stash $(date +%s)" || true
      if ! git -C "$SOURCE_DIR" pull --rebase; then
        echo "[ERROR] git pull still failing after stash. Please inspect $SOURCE_DIR."
        exit 1
      fi
    fi
  else
    echo "Cloning source to $SOURCE_DIR..."
    git clone https://github.com/autonomy-logic/orchestrator-agent.git "$SOURCE_DIR"
  fi

  # Build locally for the host architecture
  # Use 'docker build' which builds for the local machine arch (simplest and most reliable for fallback)
  echo "Building Docker image locally for this host architecture..."
  docker build -t "$IMAGE_NAME" "$SOURCE_DIR"

  echo "Local build completed: $IMAGE_NAME"
fi

if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
  echo "Existing container detected. Removing and recreating..."
  docker rm -f "$CONTAINER_NAME"
fi

echo "Creating new container: $CONTAINER_NAME"
docker run -d \
  --name "$CONTAINER_NAME" \
  --restart unless-stopped \
  -v "$MTLS_DIR:/root/.mtls:ro" \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v "$SHARED_VOLUME:/var/orchestrator" \
  "$IMAGE_NAME"

echo
echo
echo -e "${BOLD}${GREEN}INSTALLATION COMPLETE${RESET}"
echo -e "${GRAY}=====================================================${RESET}"
echo
echo -e "Orchestrator ID: ${BOLD}${CYAN}${CUSTOM_ID}${RESET}"
echo "The orchestrator container is running and connected to Autonomy Edge."
echo -e "${GRAY}=====================================================${RESET}"
