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

############################################
# Required env (installer contract)
############################################

: "${RUNTIME:?RUNTIME required}"
: "${RUNTIME_VERSION:?RUNTIME_VERSION required}"
: "${ARCHIVE_EXT:?ARCHIVE_EXT required}"

############################################
# Optional env
############################################

ZLH_ARTIFACT_BASE_URL="${ZLH_ARTIFACT_BASE_URL:-http://zlh-artifacts.internal.zlh:8080}"
ZLH_RUNTIME_ROOT="${ZLH_RUNTIME_ROOT:-/opt/zlh/runtimes}"
ARCHIVE_PREFIX="${ARCHIVE_PREFIX:-${RUNTIME}}"

############################################
# Derived paths
############################################

RUNTIME_ROOT="${ZLH_RUNTIME_ROOT}/${RUNTIME}"
DEST_DIR="${RUNTIME_ROOT}/${RUNTIME_VERSION}"
CURRENT_LINK="${RUNTIME_ROOT}/current"

############################################
# Logging helpers
############################################

log() {
  echo "[zlh-installer:${RUNTIME}] $*"
}

fail() {
  echo "[zlh-installer:${RUNTIME}] ERROR: $*" >&2
  exit 1
}

############################################
# Artifact helpers
############################################

artifact_name() {
  echo "${ARCHIVE_PREFIX}-${RUNTIME_VERSION}.${ARCHIVE_EXT}"
}

artifact_url() {
  echo "${ZLH_ARTIFACT_BASE_URL%/}/devcontainer/${RUNTIME}/${RUNTIME_VERSION}/$(artifact_name)"
}

############################################
# Download / extract
############################################

download_artifact() {
  local url out
  url="$(artifact_url)"
  out="/tmp/$(artifact_name)"

  log "action=artifact_fetch step=download url=${url} target=${out}"
  if command -v curl >/dev/null 2>&1; then
    curl -fL "${url}" -o "${out}"
  elif command -v wget >/dev/null 2>&1; then
    wget -O "${out}" "${url}"
  else
    fail "curl or wget is required"
  fi
  log "action=artifact_fetch step=download status=ok url=${url} target=${out}"
}

extract_artifact() {
  local out
  out="/tmp/$(artifact_name)"

  log "action=artifact_extract step=extract source=${out} target=${DEST_DIR}"
  mkdir -p "${DEST_DIR}"

  case "${ARCHIVE_EXT}" in
    tar.xz|tar.gz)
      tar -xf "${out}" -C "${DEST_DIR}" --strip-components=1
      ;;
    *)
      fail "Unsupported archive type: ${ARCHIVE_EXT}"
      ;;
  esac
  log "action=artifact_extract step=extract status=ok source=${out} target=${DEST_DIR}"
}

############################################
# Runtime wiring
############################################

update_symlinks() {
  ln -sfn "${DEST_DIR}" "${CURRENT_LINK}"
  ln -sfn "${CURRENT_LINK}/bin" "${RUNTIME_ROOT}/bin"
}

write_profile() {
  cat >/etc/profile.d/zlh-${RUNTIME}.sh <<EOF
export PATH="${RUNTIME_ROOT}/bin:\$PATH"
EOF
  chmod +x /etc/profile.d/zlh-${RUNTIME}.sh
}

############################################
# SSH host key initialization
############################################

ensure_ssh_host_keys() {
  # SSH may not be installed in all templates — do not fail
  if ! command -v ssh-keygen >/dev/null 2>&1; then
    log "ssh-keygen not present, skipping SSH host key setup"
    return 0
  fi

  if ls /etc/ssh/ssh_host_*_key >/dev/null 2>&1; then
    log "SSH host keys already exist"
    return 0
  fi

  log "Generating SSH host keys"
  ssh-keygen -A

  # Best-effort service restart (container init systems vary)
  systemctl enable ssh >/dev/null 2>&1 || true
  systemctl restart ssh >/dev/null 2>&1 || \
  systemctl restart sshd >/dev/null 2>&1 || true
}

############################################
# Entry point
############################################

install_runtime() {
  log "action=artifact_install runtime=${RUNTIME} version=${RUNTIME_VERSION} target=${DEST_DIR} status=begin"

  mkdir -p "${RUNTIME_ROOT}"

  if [[ -d "${DEST_DIR}" ]]; then
    log "action=artifact_install runtime=${RUNTIME} version=${RUNTIME_VERSION} target=${DEST_DIR} status=already_installed"
  else
    download_artifact
    extract_artifact
  fi

  update_symlinks
  write_profile
  chmod -R 755 "${DEST_DIR}"

  ensure_ssh_host_keys

  log "action=artifact_install runtime=${RUNTIME} version=${RUNTIME_VERSION} target=${DEST_DIR} status=ok"
}
