#!/bin/sh
# ═══════════════════════════════════════════════════════════════════════════
# SEMURG HOT UPGRADE SCRIPT
# ═══════════════════════════════════════════════════════════════════════════
#
# Usage:
#   bin/hot_upgrade <version>
#
# Unpacks and installs a new release version on a running node.
# The new tarball must be placed in releases/<version>/semurg.tar.gz
# before running this script.

set -eu

cd -P -- "$(dirname -- "$(readlink -f -- "$0")")"

VERSION="${1:?Usage: bin/hot_upgrade <version>}"
RELEASE_DIR="$(cd .. && pwd)"

echo "═══ SEMURG HOT UPGRADE to v${VERSION} ═══"

# Check the release is running
if ! ./semurg pid > /dev/null 2>&1; then
  echo "ERROR: semurg is not running. Use bin/server start instead."
  exit 1
fi

# Check the tarball exists
TARBALL="${RELEASE_DIR}/releases/${VERSION}/semurg.tar.gz"
if [ ! -f "$TARBALL" ]; then
  echo "ERROR: Release tarball not found: ${TARBALL}"
  echo "Place the built release at: ${TARBALL}"
  exit 1
fi

echo "Unpacking release v${VERSION}..."
./semurg eval "
  IO.puts(\"Connected to running node: #{Node.self()}\")
  IO.puts(\"Current version: #{Application.spec(:core_interface, :vsn)}\")
"

echo "Installing release v${VERSION}..."
# Use the release's built-in upgrade mechanism
./semurg eval "
  release_dir = \"${RELEASE_DIR}/releases/${VERSION}\"
  
  # Load new BEAM files
  {:ok, files} = File.ls(release_dir)
  beam_files = Enum.filter(files, &String.ends_with?(&1, \".beam\"))
  
  Enum.each(beam_files, fn file ->
    module = file |> String.trim_trailing(\".beam\") |> String.to_atom()
    path = Path.join(release_dir, file) |> String.to_charlist()
    case :code.load_binary(module, path, File.read!(Path.join(release_dir, file))) do
      {:module, ^module} -> IO.puts(\"  ✅ Upgraded: #{module}\")
      {:error, reason} -> IO.puts(\"  ❌ Failed: #{module} — #{inspect(reason)}\")
    end
  end)
  
  IO.puts(\"Hot upgrade complete.\")
"

echo "═══ HOT UPGRADE COMPLETE ═══"
