#!/bin/bash
# Fetches the native arm64 Steam client from Valve's client-update CDN into ~/.local/share/Steam.
# The client is not redistributable, so the runtime ships this script instead of the client.
set -eu
cdn=https://client-update.fastly.steamstatic.com
steam_channel=${BL_STEAM_CHANNEL:-steamdeck_publicbeta}
case "$steam_channel" in
  publicbeta|steamdeck_publicbeta) ;;
  *) echo "droiddeck-steam-install: unsupported Steam channel: $steam_channel" >&2; exit 1 ;;
esac
manifest=steam_client_${steam_channel}_linuxarm64
steam_root=${XDG_DATA_HOME:-$HOME/.local/share}/Steam
stamp=$steam_root/package/droiddeck-installed
legacy_stamp=$steam_root/package/bannerlator-installed
unconfirmed=$steam_root/package/droiddeck-unconfirmed
repair_request=$HOME/.bl-steam-repair
if [ -f "$legacy_stamp" ] && [ ! -f "$stamp" ]; then
  mv -f "$legacy_stamp" "$stamp" || true
fi
repair=""
if [ -e "$repair_request" ]; then
  repair="requested"
elif [ -f "$unconfirmed" ] && ! grep -qx repaired "$unconfirmed" \
    && [ "$(grep -cx start "$unconfirmed")" -ge 2 ]; then
  repair="the client was started $(grep -cx start "$unconfirmed") times without showing anything"
fi
if [ -n "$repair" ]; then
  echo "== STEP $(date -u +%H:%M:%S) repairing the Steam client ($repair)"
  rm -f "$stamp" "$legacy_stamp" "$steam_root/.crash" "$steam_root/steam.pid" \
    "$steam_root"/package/steam_client_*.manifest "$steam_root"/package/steam_client_*.installed
  for part in "$steam_root"/package/*.zip.*; do
    [ -f "$part" ] || continue
    sum=${part##*.}
    sum=${sum%%_*}
    case $sum in
      *[!0-9a-f]*|"") continue ;;
    esac
    [ ${#sum} -eq 40 ] || continue
    [ "$(sha1sum "$part" | cut -d' ' -f1)" = "$sum" ] || rm -f "$part"
  done
fi
[ -x "$steam_root/steamrtarm64/steam" ] && [ -f "$stamp" ] && exit 0

work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT
curl -fsSL "$cdn/$manifest" -o "$work/manifest"
version=$(awk -F'"' '$2 == "version" { print $4; exit }' "$work/manifest")
# Every component block: its name, then the plain zip's file name and sha256.
awk -F'"' '
  /^\t"/ && NF >= 3 && $4 == "" { block = $2 }
  $2 == "file" { file[block] = $4 }
  $2 == "sha2" { sha[block] = $4 }
  END { for (b in file) if (b ~ /_all$/ || b ~ /_linuxarm64_linuxarm64$/) print b, file[b], sha[b] }
' "$work/manifest" | sort > "$work/parts"
[ -s "$work/parts" ] || { echo "droiddeck-steam-install: no client components in $manifest" >&2; exit 1; }
total=$(grep -c . "$work/parts" 2>/dev/null || echo 0)

mkdir -p "$steam_root/package"
while read -r block file sum; do
  i=$((${i:-0} + 1))
  echo "== STEP $(date -u +%H:%M:%S) downloading Steam: $block ($i/$total)"
  curl -fsSL "$cdn/$file" -o "$work/$file"
  echo "$sum  $work/$file" | sha256sum -c --quiet
  unzip -qo "$work/$file" -d "$steam_root"
  rm -f "$work/$file"
done < "$work/parts"
# Some entries are zipped with Windows separators; unzip keeps the backslash in the file name.
find "$steam_root" -depth -name '*\\*' | while read -r odd; do
  fixed=${odd//\\//}
  mkdir -p "$(dirname "$fixed")"
  if [ -d "$odd" ]; then
    cp -a "$odd/." "$fixed/" && rm -rf "$odd"
  else
    mv -f "$odd" "$fixed"
  fi
done
echo "$steam_channel" > "$steam_root/package/beta"
ln -sfn "$steam_root/steamrtarm64" "$steam_root/steamrtarm32"
chmod +x "$steam_root/steamrtarm64/steam" 2>/dev/null || true
# What Valve's steam.sh sets up before it runs the client (it has no arm64 branch itself).
mkdir -p "$HOME/.steam"
ln -sfn "$steam_root" "$HOME/.steam/root"
ln -sfn "$steam_root" "$HOME/.steam/steam"
ln -sfn "$steam_root/steamrtarm64" "$HOME/.steam/bin64"
ln -sfn "$steam_root/linuxarm64" "$HOME/.steam/sdk64"
# The arm64 client runs every game through $HOME/.steam/sdkarm64/steam-launch-wrapper. Valve's
# steam.sh has no arm64 branch to create it, and without it a launch dies in /bin/sh before Proton
# is ever invoked - "No such file or directory", no Proton log, and the only other clue is an
# unrelated-looking installscript assertion. Same target as sdk64; the client picks the name by
# architecture.
ln -sfn "$steam_root/linuxarm64" "$HOME/.steam/sdkarm64"
ln -sfn "$steam_root/steamrtarm64" "$HOME/.steam/binarm64"
ln -sfn "$steam_root/linux32" "$HOME/.steam/sdk32"
echo "$version" > "$stamp"
if [ -n "$repair" ]; then
  echo repaired > "$unconfirmed"
  rm -f "$repair_request"
fi
