#!/usr/bin/env sh

# To fetch and run this program, you can use 'curl' or 'wget' on 'get.speedify.com'
# and then pipe the output to a super-user shell, like so:
#   bash -c "$(curl -sL https://get.speedify.com)"
# or
#   bash -c "$(wget -qO- https://get.speedify.com)"
#
# For more options, see the --help menu:
#   bash -c "$(curl -sL https://get.speedify.com)" -- --help

pkg_fail_verbose_defaultmessage () {
  echo "
This program is unable to perform an automatic installation.

You can always install Speedify manually and reach out to our support line.

The support line is here:
  support@speedify.com

Attach this to your support query for better assistance:
  System:
    $(pkg_query_system_prettyname)
    $(pkg_query_system_longname)
    $(uname -m)

Refer to these articles when performing a manual installation:
  Debian-derivates: https://support.speedify.com/article/562-how-to-install-speedify-on-linux
  OpenWrt: https://support.speedify.com/article/922-manually-installing-on-openwrt
"
  [ -n "$@" ] \
    && printf "Here's what happened:\n%s\n" "$@"
  return 1
}
pkg_die_verbose_defaultmessage () {
  pkg_fail_verbose_defaultmessage "$@"
  exit 1
}
pkg_die () {
  echo "$@"
  exit 1
}
pkg_sys_support_msg () {
  echo "\
We currently support Debian-based and OpenWrt Linux distributions.
Your system:
  $(pkg_query_system_prettyname)
  $(pkg_query_system_longname)
  $(uname -m)
Is not officially supported at the moment.
Please attach this message in an email to our support line:
  support@speedify.com
So that we can make a note of your system for future support."
}
pkg_query_system_prettyname () {
  if [ -f /etc/os-release ]; then
    cat /etc/os-release \
      | grep -E "^NAME.*$" \
      | sed -E "s/^NAME=\"(.*)\"$/\1/g"
  elif uname | grep -q Darwin; then
    echo "Apple MacOS"
  elif command -v ubus 2> /dev/null; then
    echo "OpenWRT"
  else
    echo "Unknown"
  fi
}
pkg_query_system_longname () {
  uname -a
}
pkg_query_apt_path_keyring () {
  echo "/usr/share/keyrings/connectify-archive-keyring.gpg"
}
pkg_query_apt_path_listd () {
  echo "/etc/apt/sources.list.d/connectify.list"
}
pkg_query_apt_uri_repo () {
  echo "http://apt.connectify.me/"
}
pkg_query_apt_uri_key () {
  echo "https://get.speedify.com/pgp.key"
}
pkg_query_apt_key () {
  echo "-----BEGIN PGP PUBLIC KEY BLOCK-----

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
=ZvHK
-----END PGP PUBLIC KEY BLOCK-----
"
}
pkg_query_apt_listd () {
  echo "deb [signed-by=$(pkg_query_apt_path_keyring)] $(pkg_query_apt_uri_repo) speedify main"
}
pkg_query_apt_viable () {
  command -v apt 1> /dev/null 2>& 1
}
pkg_query_linux_deps () {
  echo gpg
}
pkg_fetch () {
  if command -v wget 1> /dev/null 2>& 1; then
    wget -q "$1" || pkg_die_verbose_defaultmessage "Could not fetch '$1' with wget, ec: $?"
  elif pkg_query_opkg_viable; then
    echo "Installing wget..."
    opkg install wget || pkg_die "Failed: opkg install wget"
    wget -q "$1" || pkg_die_verbose_defaultmessage "Could not fetch '$1' with wget, ec: $?"
  elif command -v curl 1> /dev/null 2>& 1; then
    curl -s "$1" -o "$(basename "$1")" || pkg_die_verbose_defaultmessage "Could not fetch '$1' with curl, ec: $?"
  else
    pkg_die_verbose_defaultmessage "re-run this program after installing either 'curl' or 'wget'."
  fi
  echo "Fetched $1"
}
pkg_query_key () {
  echo "$(pkg_query_apt_key)"
}
pkg_query_name () {
  if [ -z "$DISPLAY" ]; then
    echo "speedify"
  else
    echo "speedifyui"
  fi
}
pkg_query_board_is_gl_inet () {
  grep -q glinet /etc/opkg/distfeeds.conf 1> /dev/null 2>& 1 || \
    grep -q glinet /etc/apk/repositories.d/distfeeds.list 1> /dev/null 2>& 1
}
pkg_query_openwrt_version () {
  ubus call system board | grep '"version":' | grep -oE '[0-9\.]+'
}
pkg_apt_sync_rm () {
  export DEBIAN_FRONTEND="noninteractive"
  sudo apt-get purge -y -qq "speedifyui"
  sudo apt-get purge -y -qq "speedify"
  sudo rm -rf \
    "$(pkg_query_apt_path_keyring)" \
    "$(pkg_query_apt_path_listd)"
}
pkg_apt_sync_deps () {
  for dep in $(pkg_query_linux_deps); do
    if ! command -v "$dep" 1> /dev/null 2>& 1; then
      sudo apt-get update -y -qq --fix-missing
      sudo apt-get install -y -qq "$dep" \
        || pkg_die_verbose_defaultmessage \
          "could not install the dependency $dep"
    fi
  done
}
pkg_apt_sync () {
  export DEBIAN_FRONTEND="noninteractive"
  if echo "$@" | grep -q -- --no-ui; then
    pkgname=speedify
  elif echo "$@" | grep -q -- --ui; then
    pkgname=speedifyui
  elif [ -z "$DISPLAY" ]; then
    pkgname=speedify
  else
    pkgname=speedifyui  # Depends on Speedify, both will be installed.
  fi
  pkg_apt_sync_deps
  pkg_query_apt_viable || pkg_die "apt is not viable or not installed"
  { pkg_query_key | gpg --quiet --dearmor | sudo tee "$(pkg_query_apt_path_keyring)" 1> /dev/null 2>& 1 ; }
  { pkg_query_apt_listd | sudo tee "$(pkg_query_apt_path_listd)" 1> /dev/null 2>& 1 ; }
  sudo apt-get update -y -qq --fix-missing
  sudo apt-cache show "$(pkg_query_name)" \
    | grep -q "Unable to locate package $(pkg_query_name)" \
    && pkg_die_verbose_defaultmessage "
    No viable package was found.
    This usually means that no package exists for your computer's architecture, $(uname -m)."
  sudo apt-get install -y -qq --no-install-recommends \
    "$(pkg_query_name)" \
    && printf "\n%s\n\n" \
      "Successfully installed $(pkg_query_name)"
}
pkg_query_opkg_viable () {
  command -v opkg 1> /dev/null 2>& 1 && [ -f /etc/openwrt_release ]
}
pkg_query_apk_viable () {
  command -v apk 1> /dev/null 2>& 1 && [ -f /etc/openwrt_release ]
}
pkg_query_opkg_arch () {
  opkg_arch=$(opkg info kernel | grep Architecture: | cut -d ' ' -f 2 | tail -n 1)
  if [ $? -ne 0 ] || [ -z "$opkg_arch" ]; then
    echo "\
ec = $ec
Could not determine the architecture of this device. Diagnostics:
Ubus system board:
$(ubus call system board)
Known, installed architectures:
$(opkg print-architecture)
" 1>&2
    return 1
  fi
  echo "$opkg_arch"
}
supported_ipks() {
  cat <<EOF
aarch64_cortex-a53
aarch64_cortex-a53_neon-vfpv4
aarch64_cortex-a72
aarch64_cortex-a76
aarch64_generic
arm_cortex-a15_neon-vfpv4
arm_cortex-a7
arm_cortex-a7_neon-vfpv4
arm_cortex-a9
arm_cortex-a9_vfpv3-d16
glibc_x86_64
x86_64
EOF
}
pkg_query_apk_arch () {
  if [ -f /etc/apk/arch ]; then
    apk_arch=$(cat /etc/apk/arch)
  else
    apk_arch=""
  fi
  if [ -z "$apk_arch" ]; then
    echo "\
Could not determine the architecture of this device. Diagnostics:
/etc/apk/arch not found or empty
" 1>&2
    return 1
  fi
  echo "$apk_arch"
}
pkg_opkg_sync () {
  opkg_arch=$(pkg_query_opkg_arch) || pkg_die_verbose_defaultmessage "Could not determine architecture"
  if ! supported_ipks | grep -q -- "^$opkg_arch$"; then
    pkg_die_verbose_defaultmessage "No package available for $opkg_arch"
  fi
  echo "Updating opkg..."
  opkg update || pkg_die "Failed: opkg update"
  [ -d /tmp/sfy-pkgs ] || mkdir -p /tmp/sfy-pkgs
  trap 'rm -rf /tmp/sfy-pkgs' EXIT
  cd /tmp/sfy-pkgs
  speedify_ipk_name=speedify_${opkg_arch}.ipk
  if pkg_query_board_is_gl_inet; then
    luci_app_speedify_ipk_name=luci-app-speedify_glinet_all.ipk
  else
    luci_app_speedify_ipk_name=luci-app-speedify_all.ipk
  fi
  if echo "$@" | grep -q -- --no-ui; then
    echo "Installing ${speedify_ipk_name} for architecture ${opkg_arch}..."
    pkg_fetch "https://downloads.speedify.com/${speedify_ipk_name}" || pkg_die "No such package: '${speedify_ipk_name}'"
    opkg install "./${speedify_ipk_name}" || pkg_die "Failed: opkg install ${speedify_ipk_name}"
  else
    echo "Installing ${speedify_ipk_name}, ${luci_app_speedify_ipk_name} for architecture ${opkg_arch}..."
    pkg_fetch "https://downloads.speedify.com/${speedify_ipk_name}" || pkg_die "No such package: '${speedify_ipk_name}'"
    pkg_fetch "https://downloads.speedify.com/${luci_app_speedify_ipk_name}" || pkg_die "No such package: '${luci_app_speedify_ipk_name}'"
    opkg install "./${speedify_ipk_name}" "./${luci_app_speedify_ipk_name}" || pkg_die "Failed: opkg install ${speedify_ipk_name} ${luci_app_speedify_ipk_name}"
  fi
}
pkg_apk_sync () {
  apk_arch=$(pkg_query_apk_arch) || pkg_die_verbose_defaultmessage "Could not determine architecture"
  if ! supported_ipks | grep -q -- "^$apk_arch$"; then
    pkg_die_verbose_defaultmessage "No package available for $apk_arch"
  fi
  echo "Updating apk..."
  apk update || pkg_die "Failed: apk update"
  [ -d /tmp/sfy-pkgs ] || mkdir -p /tmp/sfy-pkgs
  trap 'rm -rf /tmp/sfy-pkgs' EXIT
  cd /tmp/sfy-pkgs
  speedify_apk_name=speedify_${apk_arch}.apk
  if pkg_query_board_is_gl_inet; then
    luci_app_speedify_apk_name=luci-app-speedify_glinet_noarch.apk
  else
    luci_app_speedify_apk_name=luci-app-speedify_noarch.apk
  fi
  if echo "$@" | grep -q -- --no-ui; then
    echo "Installing ${speedify_apk_name} for architecture ${apk_arch}..."
    pkg_fetch "https://downloads.speedify.com/${speedify_apk_name}" || pkg_die "No such package: '${speedify_apk_name}'"
    apk add --allow-untrusted "./${speedify_apk_name}" || pkg_die "Failed: apk add ${speedify_apk_name}"
  else
    echo "Installing ${speedify_apk_name}, ${luci_app_speedify_apk_name} for architecture ${apk_arch}..."
    pkg_fetch "https://downloads.speedify.com/${speedify_apk_name}" || pkg_die "No such package: '${speedify_apk_name}'"
    pkg_fetch "https://downloads.speedify.com/${luci_app_speedify_apk_name}" || pkg_die "No such package: '${luci_app_speedify_apk_name}'"
    apk add --allow-untrusted "./${speedify_apk_name}" "./${luci_app_speedify_apk_name}" || pkg_die "Failed: apk add ${speedify_apk_name} ${luci_app_speedify_apk_name}"
  fi
}
pkg_sync_rm () {
  echo "Removing $(pkg_query_name)..."
  if pkg_query_apt_viable; then
    pkg_apt_sync_rm
  elif pkg_query_opkg_viable; then
    opkg remove --force-remove luci-app-speedify speedify
  elif pkg_query_apk_viable; then
    apk del luci-app-speedify speedify
  else
    pkg_die "Could not remove $(pkg_query_name)
$(pkg_sys_support_msg)"
  fi
}
pkg_sync () {
  echo "[This may take some time on some systems]"
  [ "$(whoami 2> /dev/null || echo '')" = "root" ] && echo "[Warning: Running as root]"
  if pkg_query_apt_viable; then
    echo "Installing $(pkg_query_name) with apt..."
    pkg_apt_sync "$@"
  elif pkg_query_opkg_viable; then
    echo "\
  Speedify must restart networking on this router to be installed correctly.
  - If you are connected to your router over wifi, you may lose your connection and join another wifi network.
    Please ensure that you are connected to the router's wifi network in a few moments.
  - If you are connected to your router over ethernet, your connection may be interrupted momentarily."
    if [ -t 0 ]; then
      echo -n 'Continue? [Enter/Y/n] '
      read -r inp
      [ "$inp" = "y" ] || [ "$inp" = "Y" ] || [ "$inp" = "" ] || pkg_die "Installation cancelled."
    fi
    echo "Installing $(pkg_query_name) with opkg..."
    pkg_opkg_sync "$@"
  elif pkg_query_apk_viable; then
    echo "\
  Speedify must restart networking on this router to be installed correctly.
  - If you are connected to your router over wifi, you may lose your connection and join another wifi network.
    Please ensure that you are connected to the router's wifi network in a few moments.
  - If you are connected to your router over ethernet, your connection may be interrupted momentarily."
    if [ -t 0 ]; then
      echo -n 'Continue? [Enter/Y/n] '
      read -r inp
      [ "$inp" = "y" ] || [ "$inp" = "Y" ] || [ "$inp" = "" ] || pkg_die "Installation cancelled."
    fi
    echo "Installing $(pkg_query_name) with apk..."
    pkg_apk_sync "$@"
  else
    pkg_die "Could not install $(pkg_query_name)
$(pkg_sys_support_msg)"
  fi
  echo "Speedify has been installed!"
  echo "Here are some resources you might find useful:"
  echo "  - CLI Documentation: https://support.speedify.com/article/285-speedify-cli"
  echo "    Running 'speedify_cli --help' is also a good start"
  echo "  - Getting started on Linux: https://support.speedify.com/article/571-getting-started-linux"
  echo "  - Some notes for Speedify on OpenWrt: https://support.speedify.com/article/918-openwrt"
}
if echo "$@" | grep -q -- --help || echo "$@" | grep -q -- -h
then
  cat <<EOF
Everything you need to get started with Speedify on Linux.

Usage: $0 [--rm|--no-ui|--help|-h]
      --rm       Remove all traces of Speedify from this system.
      --no-ui    Only install the CLI, daemon package.
                 On OpenWrt, this avoids installing a Luci plugin.
                 On other Linux distros, this avoids installing a GUI.
  -h, --help     Display this help message and exit.

For additional information, check here:
   https://support.speedify.com/article/562-how-to-install-speedify-on-linux
EOF
  exit 0
elif [ "${1-}" = "--rm" ]
then pkg_sync_rm
else pkg_sync "$@"
fi
