#!/usr/bin/env sh
set -eu

# Links to scripts/configs
scripts="https://raw.githubusercontent.com/simplex-chat/simplexmq/stable/scripts/main"
scripts_systemd_smp="$scripts/smp-server.service"
scripts_systemd_xftp="$scripts/xftp-server.service"
scripts_update="$scripts/simplex-servers-update"
scripts_uninstall="$scripts/simplex-servers-uninstall"
scripts_stopscript="$scripts/simplex-servers-stopscript"

# Default installation paths
path_bin="/usr/local/bin"
path_bin_smp="$path_bin/smp-server"
path_bin_xftp="$path_bin/xftp-server"
path_bin_update="$path_bin/simplex-servers-update"
path_bin_uninstall="$path_bin/simplex-servers-uninstall"
path_bin_stopscript="$path_bin/simplex-servers-stopscript"

path_systemd="/etc/systemd/system"
path_systemd_smp="$path_systemd/smp-server.service"
path_systemd_xftp="$path_systemd/xftp-server.service"

# Temporary paths
path_tmp_bin="$(mktemp -d)"
path_tmp_bin_update="$path_tmp_bin/simplex-servers-update"
path_tmp_bin_uninstall="$path_tmp_bin/simplex-servers-uninstall"
path_tmp_bin_stopscript="$path_tmp_bin/simplex-servers-stopscript"
path_tmp_systemd_smp="$path_tmp_bin/smp-server.service"
path_tmp_systemd_xftp="$path_tmp_bin/xftp-server.service"

path_conf_etc='/etc/opt'
path_conf_info='/etc/opt/simplex-info'

GRN='\033[0;32m'
BLU='\033[1;36m'
YLW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

# Currently, XFTP default to v0.1.0, so it doesn't make sense to check its version

os_test() {
 . /etc/os-release

 case "$VERSION_ID" in
  20.04|22.04) : ;;
  24.04) VERSION_ID='22.04' ;;
  *) printf "${RED}Unsupported Ubuntu version!${NC}\nPlease file Github issue with request to support Ubuntu %s: https://github.com/simplex-chat/simplexmq/issues/new\n" "$VERSION_ID" && exit 1 ;;
 esac

 version="$(printf '%s' "$VERSION_ID" | tr '.' '_')"
 arch="$(uname -p)"

 case "$arch" in
  x86_64) arch="$(printf '%s' "$arch" | tr '_' '-')" ;;
  *)  printf "${RED}Unsupported architecture!${NC}\nPlease file Github issue with request to support %s architecture: https://github.com/simplex-chat/simplexmq/issues/new" "$arch" && exit 1 ;;
 esac

 bin_smp="$bin/smp-server-ubuntu-${version}-${arch}"
 bin_xftp="$bin/xftp-server-ubuntu-${version}-${arch}"
}

installed_test() {
  set +u
  for i in $path_conf_etc/*; do
    if [ -d "$i" ]; then
      case "$i" in
        *simplex) apps="smp $apps" ;;
        *simplex-xftp) apps="xftp $apps" ;;
      esac
    fi
  done
  set -u
}

set_version() {
  ver="${VER:-latest}"

  case "$ver" in 
    latest)
      bin="https://github.com/simplex-chat/simplexmq/releases/latest/download"
      remote_version="$(curl --proto '=https' --tlsv1.2 -sSf -L https://api.github.com/repos/simplex-chat/simplexmq/releases/latest | grep -i "tag_name" | awk -F \" '{print $4}')"
      ;;
    *)
      bin="https://github.com/simplex-chat/simplexmq/releases/download/${ver}"
      remote_version="${ver}"
      ;;
  esac
}

update_scripts() {
  curl --proto '=https' --tlsv1.2 -sSf -L "$scripts_update" -o "$path_tmp_bin_update" && chmod +x "$path_tmp_bin_update"
  curl --proto '=https' --tlsv1.2 -sSf -L "$scripts_uninstall" -o "$path_tmp_bin_uninstall" && chmod +x "$path_tmp_bin_uninstall"
  curl --proto '=https' --tlsv1.2 -sSf -L "$scripts_stopscript" -o "$path_tmp_bin_stopscript" && chmod +x "$path_tmp_bin_stopscript"

  if diff -q "$path_bin_uninstall" "$path_tmp_bin_uninstall" > /dev/null 2>&1; then
    printf -- "- ${YLW}Uninstall script is up-to-date${NC}.\n"
    rm "$path_tmp_bin_uninstall"
  else
    printf -- "- Updating uninstall script..."
    mv "$path_tmp_bin_uninstall" "$path_bin_uninstall"
    printf "${GRN}Done!${NC}\n"
  fi

  if diff -q "$path_bin_stopscript" "$path_tmp_bin_stopscript" > /dev/null 2>&1; then
    printf -- "- ${YLW}Stopscript script is up-to-date${NC}.\n"
    rm "$path_tmp_bin_stopscript"
  else
    printf -- "- Updating stopscript script..."
    mv "$path_tmp_bin_stopscript" "$path_bin_stopscript"
    printf "${GRN}Done!${NC}\n"
  fi

  if diff -q "$path_bin_update" "$path_tmp_bin_update" > /dev/null 2>&1; then
    printf -- "- ${YLW}Update script is up-to-date${NC}.\n"
    rm "$path_tmp_bin_update"
  else
    printf -- "- Updating update script..."
    mv "$path_tmp_bin_update" "$path_bin_update"
    printf "${GRN}Done!${NC}\n"
    printf -- "- Re-executing Update script with latest updates..."
    exec sh "$path_bin_update" "continue"
  fi
}

update_systemd() {
  service="${1}-server"
  eval "scripts_systemd=\$scripts_systemd_${1}"
  eval "path_systemd=\$path_systemd_${1}"
  eval "path_tmp_systemd=\$path_tmp_systemd_${1}"
   
  curl --proto '=https' --tlsv1.2 -sSf -L "$scripts_systemd" -o "$path_tmp_systemd"

  if diff -q "$path_systemd" "$path_tmp_systemd" > /dev/null 2>&1; then
    printf -- "- ${YLW}%s service is up-to-date${NC}.\n" "$service"
    rm "$path_tmp_systemd"
  else
    printf -- "- Updating %s service..." "$service"
    mv "$path_tmp_systemd" "$path_systemd"
    systemctl daemon-reload
    printf "${GRN}Done!${NC}\n"
  fi

  unset service scripts_systemd path_systemd path_tmp_systemd
}

update_bins() {
  service="${1}-server"
  eval "bin=\$bin_${1}"
  eval "path_bin=\$path_bin_${1}"

  set_ver() {
    local_version='unset'
    sed -i -- "s/local_version_${1}=.*/local_version_${1}='${remote_version}'/" "$path_conf_info/release"
  }

  if [ -f "$path_conf_info/release" ]; then
    . "$path_conf_info/release" 2>/dev/null

    set +u
    eval "local_version=\$local_version_${1}"
    set -u

    if [ -z "${local_version}" ]; then
            set_ver "$1"
    fi
  else
    printf 'local_version_xftp=\nlocal_version_smp=\n' > "$path_conf_info/release"
    set_ver "$1"
  fi

  if [ "$local_version" != "$remote_version" ]; then
    if systemctl is-active --quiet "$service"; then
      printf -- "- Stopping %s service..." "$service"
      systemctl stop "$service"
      printf "${GRN}Done!${NC}\n"

      printf -- "- Updating %s to %s..." "$service" "$remote_version"
      curl --proto '=https' --tlsv1.2 -sSf -L "$bin" -o "$path_bin" && chmod +x "$path_bin"
      printf "${GRN}Done!${NC}\n"
      
      printf -- "- Starting %s service..." "$service"
      systemctl start "$service"
      printf "${GRN}Done!${NC}\n"
    else
      printf -- "- Updating %s to %s..." "$service" "$remote_version"
      curl --proto '=https' --tlsv1.2 -sSf -L "$bin" -o "$path_bin" && chmod +x "$path_bin"
      printf "${GRN}Done!${NC}\n"
    fi
  else
    printf -- "- ${YLW}%s is up-to-date${NC}.\n" "$service"
  fi

  set_ver "$1"

  unset service bin path_bin local_version
}

checks() {
  if [ "$(id -u)" -ne 0 ]; then
    printf "This script is intended to be run with root privileges. Please re-run script using sudo.\n"
    exit 1
  fi

  set_version
  os_test
  installed_test

  mkdir -p $path_conf_info
}

main() {
  checks

  set +u
  if [ "$1" != "continue" ]; then
    set -u
    printf "Updating scripts...\n"
    update_scripts
  else
    set -u
    printf "${GRN}Done!${NC}\n"
  fi

  printf "Updating systemd services...\n"
  for i in $apps; do
    update_systemd "$i"
  done
  
  printf "Updating simplex servers...\n"
  for i in $apps; do
    update_bins "$i"
  done

  rm -rf "$path_tmp_bin"
}

main "$@"
