#!/usr/bin/env bash

set -euo pipefail

readonly ARTICLE_API_URL="https://support-splashtopbusiness.splashtop.com/api/v2/help_center/en-us/articles/360060723291.json"

work_dir=""

die() {
  printf '\nError: %s\n' "$*" >&2
  exit 1
}

cleanup() {
  # Only remove the private directory returned by mktemp; never use a broad path.
  if [[ -n "${work_dir:-}" && -d "$work_dir" ]]; then
    rm -rf -- "$work_dir"
  fi
}

trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM

printf '%s\n' \
  '============================================================' \
  '         Benchmark Computers - Splashtop SOS for Linux' \
  '============================================================' \
  '' \
  'This launcher will:' \
  '  1. Confirm that you are using a supported 64-bit Linux system and Xorg.' \
  '  2. Ask permission before installing two required system libraries.' \
  '  3. Find and download the current official Global-stack Splashtop SOS package.' \
  '  4. Extract and launch Splashtop SOS as your normal desktop user.' \
  '' \
  'When Splashtop SOS opens, give Benchmark Computers the displayed 9-digit SOS code.' \
  ''

# Running the entire launcher as root could create unsafe GUI ownership and session issues.
if (( EUID == 0 )); then
  die "Run this script as your normal logged-in desktop user, without sudo. The script will use sudo only for apt-get."
fi

if [[ "$(uname -m)" != "x86_64" ]]; then
  die "This launcher supports only 64-bit x86_64/amd64 systems. Detected: $(uname -m)."
fi

if [[ ! -r /etc/os-release ]]; then
  die "Cannot identify this Linux distribution because /etc/os-release is unavailable."
fi

# /etc/os-release is root-managed system metadata on Ubuntu and Linux Mint.
# shellcheck disable=SC1091
source /etc/os-release
case "${ID:-}" in
  ubuntu|linuxmint)
    printf 'Detected system: %s\n' "${PRETTY_NAME:-$ID}"
    ;;
  *)
    die "This launcher supports Ubuntu and Linux Mint only. Detected distribution: ${ID:-unknown}."
    ;;
esac

# Prefer the desktop's declared session type, with loginctl as a safe fallback.
session_type="${XDG_SESSION_TYPE:-}"
if [[ -z "$session_type" && -n "${XDG_SESSION_ID:-}" ]] && command -v loginctl >/dev/null 2>&1; then
  session_type="$(loginctl show-session "$XDG_SESSION_ID" --property=Type --value 2>/dev/null || true)"
fi
session_type="${session_type,,}"

# WAYLAND_DISPLAY is checked even when DISPLAY is set because Wayland often exposes XWayland too.
if [[ "$session_type" == "wayland" || -n "${WAYLAND_DISPLAY:-}" ]]; then
  die "Wayland was detected. Splashtop SOS for Linux currently requires an Xorg session. Log out, choose an Xorg/X11 session at the login screen, and run this launcher again."
fi

if [[ "$session_type" != "x11" && "$session_type" != "xorg" ]]; then
  if [[ -n "${DISPLAY:-}" && -z "${WAYLAND_DISPLAY:-}" ]]; then
    session_type="xorg"
  else
    die "An Xorg desktop session could not be confirmed. Splashtop SOS does not currently support Wayland."
  fi
fi
printf 'Detected desktop session: %s\n\n' "$session_type"

command -v apt-get >/dev/null 2>&1 || die "apt-get is required but was not found."
command -v sudo >/dev/null 2>&1 || die "sudo is required but was not found."
command -v tar >/dev/null 2>&1 || die "tar is required but was not found."
command -v grep >/dev/null 2>&1 || die "grep is required but was not found."
command -v sort >/dev/null 2>&1 || die "sort is required but was not found."
command -v find >/dev/null 2>&1 || die "find is required but was not found."

if command -v curl >/dev/null 2>&1; then
  downloader="curl"
elif command -v wget >/dev/null 2>&1; then
  downloader="wget"
else
  die "Either curl or wget is required to securely download Splashtop SOS."
fi

download_https() {
  local url="$1"
  local destination="$2"

  # Fail closed if a discovered or redirected URL is not HTTPS.
  [[ "$url" == https://* ]] || die "Refusing a non-HTTPS download URL: $url"

  if [[ "$downloader" == "curl" ]]; then
    curl --fail --location --proto '=https' --proto-redir '=https' \
      --silent --show-error --output "$destination" "$url"
  else
    wget --https-only --secure-protocol=TLSv1_2 --quiet \
      --output-document="$destination" "$url"
  fi
}

work_dir="$(mktemp -d -t benchmark-splashtop.XXXXXXXX)" || die "Could not create a temporary working directory."
article_file="$work_dir/splashtop-article.json"
url_list_file="$work_dir/global-download-urls.txt"
archive_file="$work_dir/splashtop-sos.tar.gz"
archive_list_file="$work_dir/archive-contents.txt"
extract_dir="$work_dir/extracted"

printf 'Checking Splashtop for the current official Global-stack Linux package...\n'
if ! download_https "$ARTICLE_API_URL" "$article_file"; then
  die "Could not retrieve Splashtop's official Linux SOS download information. Nothing was installed."
fi

# This strict pattern accepts only the Ubuntu amd64 Global package on Splashtop's HTTPS
# download host. EU and OC filenames do not match. Multiple or missing matches are rejected.
if ! grep -Eo 'https://download[.]splashtop[.]com/linux/STB_ASRS_Ubuntu_v[0-9]+([.][0-9]+)+_amd64[.]tar[.]gz' "$article_file" \
  | sort -u > "$url_list_file"; then
  :
fi

mapfile -t discovered_urls < "$url_list_file"
if (( ${#discovered_urls[@]} != 1 )); then
  die "Could not identify exactly one current official Global-stack Ubuntu download URL on Splashtop's page. Found ${#discovered_urls[@]}; refusing to guess."
fi
download_url="${discovered_urls[0]}"

# Re-check the complete URL before using it, rather than trusting page text blindly.
if [[ ! "$download_url" =~ ^https://download[.]splashtop[.]com/linux/STB_ASRS_Ubuntu_v[0-9]+([.][0-9]+)+_amd64[.]tar[.]gz$ ]]; then
  die "Splashtop returned an unexpected download URL; refusing to continue."
fi
printf 'Official package found: %s\n\n' "$download_url"

printf '%s\n' \
  'The following commands will now be run with sudo:' \
  '  sudo apt-get update' \
  '  sudo apt-get install -y libxcb-screensaver0 libxcb-xtest0' \
  '' \
  'sudo may ask for your Linux account password. This script never reads or stores that password.'
read -r -p 'Continue with dependency installation? [y/N] ' answer || die "Could not read your confirmation."
case "${answer,,}" in
  y|yes) ;;
  *)
    printf 'Cancelled. Nothing was installed.\n'
    exit 0
    ;;
esac

printf '\nUpdating package information...\n'
if ! sudo apt-get update; then
  die "apt-get update failed. Check your network connection and package configuration."
fi

printf '\nInstalling required libraries...\n'
if ! sudo apt-get install -y libxcb-screensaver0 libxcb-xtest0; then
  die "The required Splashtop libraries could not be installed."
fi

printf '\nDownloading Splashtop SOS from the verified official HTTPS URL...\n'
if ! download_https "$download_url" "$archive_file"; then
  die "The official Splashtop SOS package download failed."
fi
[[ -s "$archive_file" ]] || die "The downloaded package is empty."

printf 'Checking the downloaded archive...\n'
if ! tar -tzf "$archive_file" > "$archive_list_file"; then
  die "The downloaded file is not a readable gzip-compressed tar archive."
fi

# Reject absolute paths and parent-directory traversal before extraction.
while IFS= read -r archive_entry; do
  normalized_entry="${archive_entry#./}"
  case "$normalized_entry" in
    /*|../*|*/../*|*/..)
      die "The downloaded archive contains an unsafe path; refusing to extract it."
      ;;
  esac
done < "$archive_list_file"

mkdir -m 700 "$extract_dir"
if ! tar -xzf "$archive_file" --directory "$extract_dir" --no-same-owner --no-same-permissions; then
  die "Could not extract the Splashtop SOS package."
fi

# Locate a regular file with the exact expected name; do not follow links or chmod a wildcard.
mapfile -d '' -t sos_executables < <(find "$extract_dir" -type f -name 'SplashtopSOS' -print0)
if (( ${#sos_executables[@]} != 1 )); then
  die "Expected exactly one SplashtopSOS executable in the package, but found ${#sos_executables[@]}."
fi
sos_executable="${sos_executables[0]}"
chmod u+x -- "$sos_executable"

printf '%s\n' \
  '' \
  'Launching Splashtop SOS as your normal desktop user...' \
  'Give Benchmark Computers the displayed 9-digit SOS code.' \
  ''

# The script itself is not elevated; only the two apt-get commands above use sudo.
sos_status=0
(
  cd "$(dirname -- "$sos_executable")"
  "./$(basename -- "$sos_executable")"
) || sos_status=$?

if (( sos_status != 0 )); then
  die "Splashtop SOS exited with status $sos_status."
fi

printf 'Splashtop SOS has closed. Temporary files have been removed.\n'
