#!/bin/bash
#
# Update the Moxa DLM Agent together with its matching MIL components.
#
# Why this script installs more than just the agent:
#   Each DLM Agent build is released WITH the specific MIL component versions it
#   depends on — Moxa Connection Manager (libmcm0 / moxa-connection-manager), and
#   on MIL 4 also Moxa Edge (moxa-edge) and moxa-version. Installing only the agent
#   .deb would leave those components on their old versions and can cause mismatches.
#   This script installs the agent AND its MIL companions together so they stay in sync.
#
# How to deliver it via the DLM web console (Run Custom Script):
#   1) Build ONE update bundle (.tar) that contains every .deb from the release for
#      the target device's MIL/arch, e.g.:
#         moxa-dlm-agent_*.deb
#         MIL_packages/*.deb        (libmcm0, moxa-connection-manager, moxa-edge, moxa-version, ...)
#   2) In the DLM web console: select the device(s) -> Run custom script
#      -> upload THIS script as the script, and the .tar bundle as the additional file.
#
set -Eeuo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd -P)"
cd "$SCRIPT_DIR"
shopt -s nullglob

echo "== DLM Agent update =="
echo "Working directory: ${SCRIPT_DIR}"

# 1) If an update bundle was delivered alongside this script, unpack it.
bundles=( *.tar.gz *.tgz *.tar )
for b in "${bundles[@]}"; do
  echo "Extracting update bundle: ${b}"
  tar -xf "${b}"
done

# 2) Collect every .deb shipped in this update (agent + MIL companions).
mapfile -t DEBS < <(find . -maxdepth 4 -name '*.deb' | sort)
if [ "${#DEBS[@]}" -eq 0 ]; then
  echo "ERROR: No .deb packages found. Upload the agent .deb (and its MIL_packages) or a .tar bundle that contains them."
  exit 1
fi

echo "Installing ${#DEBS[@]} package(s) together so the agent and its MIL components stay in sync:"
printf '  - %s\n' "${DEBS[@]}"

# 2b) Compatibility guard: refuse a bundle built for a different MIL / architecture.
#     Derived from the agent .deb itself, so this stays correct for any package variant.
AGENT_DEB="$(printf '%s\n' "${DEBS[@]}" | grep -E '/moxa-dlm-agent_[^/]*\.deb$' | head -n1 || true)"
if [ -n "${AGENT_DEB:-}" ] && command -v dpkg-deb >/dev/null 2>&1; then
  PKG_ARCH="$(dpkg-deb -f "$AGENT_DEB" Architecture 2>/dev/null || true)"
  SYS_ARCH="$(dpkg --print-architecture 2>/dev/null || true)"
  if [ -n "${PKG_ARCH:-}" ] && [ "$PKG_ARCH" != "all" ] && [ "$PKG_ARCH" != "${SYS_ARCH}" ]; then
    echo "ERROR: This update is built for '${PKG_ARCH}', but this device is '${SYS_ARCH}'. Aborting."
    exit 1
  fi
  EXPECTED_MIL_MAJOR=""
  case "$AGENT_DEB" in
    *+deb11*) EXPECTED_MIL_MAJOR=3 ;;
    *+deb13*) EXPECTED_MIL_MAJOR=4 ;;
  esac
  if [ -n "$EXPECTED_MIL_MAJOR" ] && command -v mx-ver >/dev/null 2>&1; then
    MIL_VER="$(mx-ver -M 2>/dev/null | tr -d '[:space:]')"
    DEV_MIL_MAJOR="${MIL_VER%%.*}"
    if [ -n "${DEV_MIL_MAJOR:-}" ] && [ "$DEV_MIL_MAJOR" != "$EXPECTED_MIL_MAJOR" ]; then
      echo "ERROR: This update is for MIL ${EXPECTED_MIL_MAJOR}.x, but this device is MIL ${MIL_VER}."
      echo "       Use the MIL${DEV_MIL_MAJOR} update package instead. Aborting."
      exit 1
    fi
  fi
fi

# 3) Install all packages together; apt resolves the correct order and dependencies.
if command -v apt-get >/dev/null 2>&1; then
  if ! DEBIAN_FRONTEND=noninteractive apt-get install -y "${DEBS[@]}"; then
    echo "apt-get failed; falling back to dpkg + dependency fix..."
    dpkg -i "${DEBS[@]}" || true
    DEBIAN_FRONTEND=noninteractive apt-get -y -o APT::Install-Recommends=false install -f
  fi
else
  dpkg -i "${DEBS[@]}"
fi

# 4) Restart the agent a few seconds AFTER this script returns, so the running
#    Run-Custom-Script session is not cut off mid-update.
systemd-run --on-active=5 bash -c 'systemctl daemon-reload && systemctl restart moxa-dlm-agent'

echo "Update staged successfully. The moxa-dlm-agent service will reload in ~5 seconds."
echo "After ~30s, verify with: mx-dlm-agent status"
exit 0
