#!/bin/sh
set -eu

release_root="${STUDIOFS_RELEASE_ROOT:-https://releases.studiofs.dev/repository/raw-hosted/studiofs/dogfood}"
install_dir="${STUDIOFS_INSTALL_DIR:-/usr/local/bin}"
login=1

while [ "$#" -gt 0 ]; do
  case "$1" in
    --no-login)
      login=0
      shift
      ;;
    --install-dir)
      [ "$#" -ge 2 ] || { echo "--install-dir requires a path" >&2; exit 2; }
      install_dir=$2
      shift 2
      ;;
    *)
      echo "unknown option: $1" >&2
      exit 2
      ;;
  esac
done

platform=$(uname -s)
machine=$(uname -m)
case "${platform}:${machine}" in
  Linux:x86_64|Linux:amd64)
    target=x86_64-unknown-linux-gnu
    checksum_command=sha256sum
    ;;
  Darwin:arm64|Darwin:aarch64)
    target=aarch64-apple-darwin
    checksum_command=shasum
    ;;
  Darwin:x86_64)
    target=x86_64-apple-darwin
    checksum_command=shasum
    ;;
  *)
    echo "StudioFS does not yet publish a build for ${platform} ${machine}" >&2
    exit 1
    ;;
esac

for command in curl tar "$checksum_command"; do
  command -v "$command" >/dev/null 2>&1 || {
    echo "required system command is missing: $command" >&2
    exit 1
  }
done

work_dir=$(mktemp -d)
staged_binary="$work_dir/studiofs.new"
macfuse_mount=
cleanup() {
  if [ -n "$macfuse_mount" ]; then
    hdiutil detach "$macfuse_mount" >/dev/null 2>&1 || true
  fi
  rm -rf "$work_dir"
  rm -f "$staged_binary"
}
trap cleanup EXIT HUP INT TERM

run_as_root() {
  if [ "$(id -u)" -eq 0 ]; then
    "$@"
  elif command -v sudo >/dev/null 2>&1; then
    sudo "$@"
  else
    echo "StudioFS needs administrator approval to install its filesystem driver, but sudo is unavailable" >&2
    exit 1
  fi
}

install_linux_fuse() {
  command -v fusermount3 >/dev/null 2>&1 && return
  echo "Installing the FUSE filesystem driver required by StudioFS..."
  if command -v apt-get >/dev/null 2>&1; then
    run_as_root apt-get update -qq
    run_as_root apt-get install -y -qq fuse3
  elif command -v dnf >/dev/null 2>&1; then
    run_as_root dnf install -y fuse3
  elif command -v yum >/dev/null 2>&1; then
    run_as_root yum install -y fuse3
  elif command -v pacman >/dev/null 2>&1; then
    run_as_root pacman -S --needed --noconfirm fuse3
  elif command -v zypper >/dev/null 2>&1; then
    run_as_root zypper --non-interactive install fuse3
  else
    echo "StudioFS could not install FUSE: no supported package manager was found" >&2
    exit 1
  fi
  command -v fusermount3 >/dev/null 2>&1 || {
    echo "FUSE installation completed without providing fusermount3" >&2
    exit 1
  }
}

linux_invoking_user() {
  if [ -n "${SUDO_USER:-}" ] && [ "$SUDO_USER" != "root" ]; then
    printf '%s\n' "$SUDO_USER"
    return 0
  fi
  if [ "$(id -u)" -ne 0 ]; then
    id -un
    return 0
  fi
  echo "StudioFS could not tell which user should receive /media access. Run the installer as that user, or with sudo." >&2
  return 1
}

grant_linux_media_acl() {
  user=$(linux_invoking_user)
  if [ ! -d /media ]; then
    run_as_root mkdir -p /media
  fi
  if ! command -v setfacl >/dev/null 2>&1; then
    echo "Installing acl so StudioFS can grant /media access..."
    if command -v apt-get >/dev/null 2>&1; then
      run_as_root apt-get update -qq
      run_as_root apt-get install -y -qq acl
    elif command -v dnf >/dev/null 2>&1; then
      run_as_root dnf install -y acl
    elif command -v yum >/dev/null 2>&1; then
      run_as_root yum install -y acl
    elif command -v pacman >/dev/null 2>&1; then
      run_as_root pacman -S --needed --noconfirm acl
    elif command -v zypper >/dev/null 2>&1; then
      run_as_root zypper --non-interactive install acl
    else
      echo "StudioFS could not install acl: no supported package manager was found" >&2
      exit 1
    fi
  fi
  command -v setfacl >/dev/null 2>&1 || {
    echo "acl installation completed without providing setfacl" >&2
    exit 1
  }
  echo "Granting ${user} permission to create directories under /media..."
  run_as_root setfacl -m "u:${user}:rwx" /media
}

install_linux_user_volume() {
  script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
  user_script=$script_dir/../mesh/systemd/install-user-volume.sh
  if [ ! -f "$user_script" ]; then
    return 0
  fi
  user=$(linux_invoking_user)
  if [ "$(id -u)" -eq 0 ]; then
    user_home=$(getent passwd "$user" | awk -F: '{print $6}')
    uid=$(id -u "$user")
    if command -v runuser >/dev/null 2>&1; then
      runuser -u "$user" -- env HOME="$user_home" USER="$user" LOGNAME="$user" XDG_RUNTIME_DIR="/run/user/${uid}" "$user_script"
    else
      sudo -u "$user" -H env XDG_RUNTIME_DIR="/run/user/${uid}" "$user_script"
    fi
  else
    "$user_script"
  fi
}

install_macos_fuse() {
  for command in hdiutil installer; do
    command -v "$command" >/dev/null 2>&1 || {
      echo "required macOS command is missing: $command" >&2
      exit 1
    }
  done

  [ -d /Library/Filesystems/macfuse.fs ] && return

  macfuse_version=5.3.3
  macfuse_sha256=7a0b7b66c0e7f8932707d1215dc9cf486e178d097ae0a2dcdf17d8530566aa15
  macfuse_dmg="$work_dir/macfuse.dmg"
  macfuse_mount="$work_dir/macfuse"
  mkdir -p "$macfuse_mount"

  echo "Installing the signed macFUSE filesystem driver required by StudioFS..."
  curl --proto '=https' --tlsv1.2 --fail --silent --show-error --location \
    "https://github.com/macfuse/macfuse/releases/download/macfuse-${macfuse_version}/macfuse-${macfuse_version}.dmg" \
    -o "$macfuse_dmg"
  printf '%s  %s\n' "$macfuse_sha256" "$macfuse_dmg" | shasum -a 256 -c - >/dev/null
  hdiutil attach -nobrowse -readonly -mountpoint "$macfuse_mount" "$macfuse_dmg" >/dev/null
  macfuse_package="$macfuse_mount/Install macFUSE.pkg"
  [ -f "$macfuse_package" ] || {
    echo "The verified macFUSE image did not contain its installer package" >&2
    exit 1
  }
  run_as_root installer -pkg "$macfuse_package" -target /
  hdiutil detach "$macfuse_mount" >/dev/null
  macfuse_mount=
}

case "$platform" in
  Linux)
    install_linux_fuse
    grant_linux_media_acl
    install_linux_user_volume
    ;;
  Darwin) install_macos_fuse ;;
esac

artifact_url="${release_root}/${target}/studiofs.tar.gz"
checksum_url="${artifact_url}.sha256"
verified=0
attempt=1
while [ "$attempt" -le 3 ]; do
  curl --proto '=https' --tlsv1.2 --fail --silent --show-error --location \
    "$checksum_url" -o "$work_dir/studiofs.tar.gz.sha256"
  curl --proto '=https' --tlsv1.2 --fail --silent --show-error --location \
    "$artifact_url" -o "$work_dir/studiofs.tar.gz"
  case "$platform" in
    Linux)
      (cd "$work_dir" && sha256sum -c studiofs.tar.gz.sha256 >/dev/null 2>&1) && verified=1
      ;;
    Darwin)
      (cd "$work_dir" && shasum -a 256 -c studiofs.tar.gz.sha256 >/dev/null 2>&1) && verified=1
      ;;
  esac
  [ "$verified" -eq 0 ] || break
  attempt=$((attempt + 1))
done
[ "$verified" -eq 1 ] || {
  echo "StudioFS artifact checksum did not match after three attempts" >&2
  exit 1
}

tar -xzf "$work_dir/studiofs.tar.gz" -C "$work_dir"
[ -x "$work_dir/studiofs" ] || {
  echo "StudioFS artifact did not contain the client binary" >&2
  exit 1
}
install -m 0755 "$work_dir/studiofs" "$staged_binary"
if [ ! -d "$install_dir" ] && ! mkdir -p "$install_dir" 2>/dev/null; then
  run_as_root mkdir -p "$install_dir"
fi
if [ -w "$install_dir" ]; then
  mv -f "$staged_binary" "$install_dir/studiofs"
else
  privileged_stage="${install_dir}/.studiofs.new.$$"
  run_as_root install -m 0755 "$staged_binary" "$privileged_stage"
  run_as_root mv -f "$privileged_stage" "$install_dir/studiofs"
fi

echo "Installed verified StudioFS artifact at $install_dir/studiofs"
case ":${PATH}:" in
  *":${install_dir}:"*) ;;
  *) echo "Add ${install_dir} to PATH to run studiofs directly." ;;
esac

if [ "$login" -eq 1 ]; then
  if [ -r /dev/tty ] && [ -w /dev/tty ]; then
    "$install_dir/studiofs" login </dev/tty >/dev/tty 2>/dev/tty
  else
    "$install_dir/studiofs" login
  fi
fi
