#!/usr/bin/env bash
# Scantide Auditor Linux installer / uninstaller
# Installs the latest Scantide Linux local check script as /usr/local/bin/scantide-linux
# Uninstall with: sudo ./install-scantide-linux.sh --uninstall

set -u

BASE_URL="${SCANTIDE_BASE_URL:-https://www.scantide.com/helpfiles}"
SCRIPT_URL="${SCANTIDE_LINUX_SCRIPT_URL:-$BASE_URL/scantide-linux-localcheck.sh}"
HASH_URL="${SCANTIDE_LINUX_HASH_URL:-$BASE_URL/scantide-linux-localcheck.sha256}"

INSTALL_DIR="${SCANTIDE_INSTALL_DIR:-/opt/scantide}"
BIN_PATH="${SCANTIDE_BIN_PATH:-/usr/local/bin/scantide-linux}"
SCRIPT_PATH="$INSTALL_DIR/scantide-linux-localcheck.sh"
HASH_PATH="$INSTALL_DIR/scantide-linux-localcheck.sha256"

REMOVE_REPORTS=false
ACTION="install"

for arg in "$@"; do
  case "$arg" in
    --uninstall|uninstall|remove)
      ACTION="uninstall"
      ;;
    --purge|--remove-reports)
      ACTION="uninstall"
      REMOVE_REPORTS=true
      ;;
    --help|-h)
      cat <<EOF
Scantide Auditor Linux installer

Usage:
  sudo ./install-scantide-linux.sh
  sudo ./install-scantide-linux.sh --uninstall
  sudo ./install-scantide-linux.sh --purge

Options:
  --uninstall        Remove installed command and /opt/scantide files.
  --purge           Also remove common Scantide Linux report folders.
  --remove-reports  Same as --purge.
  --help            Show this help.

Environment overrides:
  SCANTIDE_BASE_URL
  SCANTIDE_LINUX_SCRIPT_URL
  SCANTIDE_LINUX_HASH_URL
  SCANTIDE_INSTALL_DIR
  SCANTIDE_BIN_PATH
EOF
      exit 0
      ;;
  esac
done

TMP_DIR="$(mktemp -d /tmp/scantide-linux-install.XXXXXX)"

cleanup() {
  rm -rf "$TMP_DIR"
}
trap cleanup EXIT

log() {
  printf '[Scantide] %s\n' "$1"
}

fail() {
  printf '[Scantide] ERROR: %s\n' "$1" >&2
  exit 1
}

need_root() {
  if [ "$(id -u)" -ne 0 ]; then
    fail "Please run with sudo/root because this changes $INSTALL_DIR and $BIN_PATH"
  fi
}

fetch_file() {
  url="$1"
  dest="$2"

  if command -v curl >/dev/null 2>&1; then
    curl -fsSL --max-time 60 "$url" -o "$dest"
  elif command -v wget >/dev/null 2>&1; then
    wget -q --timeout=60 "$url" -O "$dest"
  else
    fail "Neither curl nor wget is installed."
  fi
}

verify_hash() {
  script="$1"
  hashfile="$2"

  if [ ! -s "$hashfile" ]; then
    log "No SHA256 file available. Continuing without hash verification."
    return 0
  fi

  if ! command -v sha256sum >/dev/null 2>&1; then
    log "sha256sum is not available. Continuing without hash verification."
    return 0
  fi

  expected="$(awk '{print $1}' "$hashfile" | head -1)"
  actual="$(sha256sum "$script" | awk '{print $1}')"

  if [ -z "$expected" ]; then
    log "SHA256 file was empty or invalid. Continuing without hash verification."
    return 0
  fi

  if [ "$expected" != "$actual" ]; then
    echo "Expected: $expected"
    echo "Actual:   $actual"
    fail "SHA256 verification failed. Refusing to install."
  fi

  log "SHA256 verification OK."
}

uninstall_scantide() {
  need_root

  log "Uninstalling Scantide Auditor Linux"

  if [ -L "$BIN_PATH" ] || [ -f "$BIN_PATH" ]; then
    rm -f "$BIN_PATH"
    log "Removed command: $BIN_PATH"
  else
    log "Command not found: $BIN_PATH"
  fi

  if [ -f "$SCRIPT_PATH" ]; then
    rm -f "$SCRIPT_PATH"
    log "Removed script: $SCRIPT_PATH"
  fi

  if [ -f "$HASH_PATH" ]; then
    rm -f "$HASH_PATH"
    log "Removed hash file: $HASH_PATH"
  fi

  # Remove install dir only if empty.
  if [ -d "$INSTALL_DIR" ]; then
    rmdir "$INSTALL_DIR" 2>/dev/null && log "Removed empty directory: $INSTALL_DIR" || log "Kept non-empty directory: $INSTALL_DIR"
  fi

  if [ "$REMOVE_REPORTS" = true ]; then
    log "Removing common Scantide Linux report folders"
    rm -rf ./scantide-linux-report 2>/dev/null || true
    rm -rf /root/scantide-linux-report 2>/dev/null || true
    rm -rf "$HOME/scantide-linux-report" 2>/dev/null || true
    log "Report folders removed where found."
  else
    log "Reports were not removed. Use --purge to remove common report folders too."
  fi

  log "Uninstall complete."
}

install_scantide() {
  need_root

  log "Installing Scantide Auditor Linux"
  log "Download URL: $SCRIPT_URL"

  tmp_script="$TMP_DIR/scantide-linux-localcheck.sh"
  tmp_hash="$TMP_DIR/scantide-linux-localcheck.sha256"

  fetch_file "$SCRIPT_URL" "$tmp_script" || fail "Could not download Scantide Linux local check script."

  if [ ! -s "$tmp_script" ]; then
    fail "Downloaded script is empty."
  fi

  # Hash is recommended but not mandatory, so a missing hash should not block first deployment.
  fetch_file "$HASH_URL" "$tmp_hash" 2>/dev/null || true
  verify_hash "$tmp_script" "$tmp_hash"

  mkdir -p "$INSTALL_DIR"
  cp "$tmp_script" "$SCRIPT_PATH"
  chmod 0755 "$SCRIPT_PATH"

  if [ -s "$tmp_hash" ]; then
    cp "$tmp_hash" "$HASH_PATH"
    chmod 0644 "$HASH_PATH"
  fi

  cat > "$BIN_PATH" <<EOF
#!/usr/bin/env bash
exec "$SCRIPT_PATH" "\$@"
EOF

  chmod 0755 "$BIN_PATH"

  log "Installed script: $SCRIPT_PATH"
  log "Installed command: $BIN_PATH"

  echo
  echo "Run:"
  echo "  sudo scantide-linux --api-key YOURKEY --email you@example.com"
  echo
  echo "Or simply:"
  echo "  sudo scantide-linux"
  echo
  echo "Uninstall:"
  echo "  sudo ./install-scantide-linux.sh --uninstall"
  echo
  echo "Reports are written to ./scantide-linux-report by default from the directory where you run the command."
}

case "$ACTION" in
  uninstall)
    uninstall_scantide
    ;;
  install)
    install_scantide
    ;;
  *)
    fail "Unknown action: $ACTION"
    ;;
esac
