#!/bin/sh
# SteamTradeX Inventory API for your Steam bot, in one command.
# Guide: https://steamtradex.com/guides/inventory-api-steam-bot
#
# In your bot's folder (the one with package.json):
#   curl -fsSL https://steamtradex.com/downloads/steam-bot/install.sh | sh -s -- inv_your_key
#
# It adds the SteamTradeX add-on to the bot's inventory library, puts your key
# in .env as STEAMTRADEX_API_KEY, and restarts the bot (PM2 or Docker). Run it
# again any time: after a bot update, or to change the key. Nothing in the
# bot's own code is changed.
#
# To switch back, and take everything out again:
#   curl -fsSL https://steamtradex.com/downloads/steam-bot/install.sh | sh -s -- remove
set -e

KEY="${1:-}"
LIB="node_modules/@luc4sguilherme/steam-inventory/src"
FROM="${STEAMTRADEX_DOWNLOAD:-https://steamtradex.com/downloads/steam-bot/steamtradex.js}"
SELF="https://steamtradex.com/downloads/steam-bot/install.sh"

say() { echo "SteamTradeX: $*"; }
fail() { say "$*"; exit 1; }

# Restarts the bot the way it is running now: PM2, or Docker (with a rebuild,
# so a Dockerfile change takes effect). Otherwise says to restart it by hand.
restart_bot() {
  if command -v pm2 >/dev/null 2>&1 && pm2 describe levelUP-bot >/dev/null 2>&1; then
    pm2 restart levelUP-bot >/dev/null && say "bot restarted. All done."
    return 0
  fi
  if docker compose version >/dev/null 2>&1; then DC="docker compose"; elif command -v docker-compose >/dev/null 2>&1; then DC="docker-compose"; else DC=""; fi
  if [ -n "$DC" ] && [ -n "$($DC ps -q bot 2>/dev/null)" ]; then
    say "rebuilding and restarting your bot (this takes a minute)..."
    $DC build && $DC up -d && say "bot restarted. All done."
    return 0
  fi
  say "now restart your bot, and you are done."
}

# Switching back: everything this script ever added comes out again, and the
# bot reads inventories exactly as it did before, with whatever is in .env.
if [ "$KEY" = "remove" ]; then
  FOUND=""
  if [ -f "$LIB/index.js" ]; then
    if grep -q "steamtradex.js" "$LIB/index.js"; then
      grep -v "steamtradex.js" "$LIB/index.js" > "$LIB/index.steamtradex.tmp" || true
      cat "$LIB/index.steamtradex.tmp" > "$LIB/index.js"
      rm -f "$LIB/index.steamtradex.tmp"
    fi
    rm -f "$LIB/steamtradex.js" "$LIB/steamtradex.download.js"
    FOUND=1
  fi
  if [ -f Dockerfile ] && grep -q "steamtradex.sh" Dockerfile; then
    grep -v "steamtradex.sh" Dockerfile > Dockerfile.steamtradex.tmp || true
    cat Dockerfile.steamtradex.tmp > Dockerfile
    rm -f Dockerfile.steamtradex.tmp
    FOUND=1
  fi
  if [ -f .env ] && grep -q "^STEAMTRADEX_API_KEY=" .env; then
    grep -v "^STEAMTRADEX_API_KEY=" .env > .env.steamtradex.tmp || true
    cat .env.steamtradex.tmp > .env
    rm -f .env.steamtradex.tmp
    FOUND=1
  fi
  [ -n "$FOUND" ] || fail "this does not look like your bot folder. Go into the folder with package.json and run it again. Nothing was changed."
  say "removed. Your bot now reads inventories the way it did before."
  restart_bot
  exit 0
fi

if [ -n "$KEY" ] && ! echo "$KEY" | grep -Eq '^inv_[A-Za-z0-9_-]{20,}$'; then
  fail "that does not look like a SteamTradeX key (it starts inv_). Copy it again from steamtradex.com/dashboard/api/keys. Nothing was changed."
fi

# Puts the add-on into the library, safely: download beside it, check it,
# then swap it in, so a failed download never leaves the bot a broken file.
add_addon() {
  TMP="$LIB/steamtradex.download.js"
  if command -v curl >/dev/null 2>&1; then
    curl -fsSL "$FROM" -o "$TMP" || { rm -f "$TMP"; fail "download failed. Nothing was changed; try again."; }
  elif command -v wget >/dev/null 2>&1; then
    wget -qO "$TMP" "$FROM" || { rm -f "$TMP"; fail "download failed. Nothing was changed; try again."; }
  else
    fail "needs curl or wget to download the add-on. Nothing was changed."
  fi
  if command -v node >/dev/null 2>&1 && ! node --check "$TMP" >/dev/null 2>&1; then
    rm -f "$TMP"
    fail "the download looks broken. Nothing was changed; try again."
  fi
  mv "$TMP" "$LIB/steamtradex.js"
  if ! grep -q "steamtradex.js" "$LIB/index.js"; then
    printf "\nrequire('./steamtradex.js')(module.exports);\n" >> "$LIB/index.js"
  fi
}

# Writes STEAMTRADEX_API_KEY into .env, replacing an old one if there is one.
set_key() {
  [ -n "$KEY" ] || return 0
  [ -f .env ] || fail "no .env file in this folder. Run this in your bot's folder. The add-on is installed; your key is not."
  grep -v '^STEAMTRADEX_API_KEY=' .env > .env.steamtradex.tmp || true
  # Keep the file's own line endings (Windows-made .env files use CRLF).
  if grep -q "$(printf '\r')" .env; then EOL="$(printf '\r')"; else EOL=""; fi
  if [ -s .env.steamtradex.tmp ] && [ -n "$(tail -c1 .env.steamtradex.tmp)" ]; then printf '\n' >> .env.steamtradex.tmp; fi
  printf 'STEAMTRADEX_API_KEY="%s"%s\n' "$KEY" "$EOL" >> .env.steamtradex.tmp
  cat .env.steamtradex.tmp > .env
  rm -f .env.steamtradex.tmp
  say "key saved in .env as STEAMTRADEX_API_KEY."
}

DID=""

# The library is here: a bot run with Node (PM2), or inside a Docker build.
if [ -f "$LIB/index.js" ]; then
  add_addon
  say "add-on installed."
  DID=1
fi

# A Docker setup: the library lives inside the image, so the add-on goes in
# the build. (Inside a Docker build there is no Dockerfile, so this is skipped.)
if [ -f Dockerfile ] && { [ -f docker-compose.yaml ] || [ -f docker-compose.yml ]; }; then
  LINE="RUN wget -qO /tmp/steamtradex.sh $SELF && sh /tmp/steamtradex.sh"
  if ! grep -q "steamtradex.sh" Dockerfile; then
    LAST=$(grep -n "^RUN npm ci" Dockerfile | tail -1 | cut -d: -f1)
    if [ -n "$LAST" ]; then
      awk -v n="$LAST" -v line="$LINE" "{ print } NR == n { print line }" Dockerfile > Dockerfile.steamtradex.tmp
      cat Dockerfile.steamtradex.tmp > Dockerfile
      rm -f Dockerfile.steamtradex.tmp
      say "add-on added to your Dockerfile."
      DID=1
    else
      say "could not find a RUN npm ci line in the Dockerfile, so Docker builds will not include the add-on."
    fi
  else
    DID=1
  fi
fi

[ -n "$DID" ] || fail "this does not look like your bot folder (no node_modules/@luc4sguilherme/steam-inventory, and no Dockerfile). Go into the folder with package.json and run it again. Nothing was changed."

set_key
[ -n "$KEY" ] || exit 0

restart_bot
