#!/bin/sh
# tinyjs installer.
#
#   curl -fsSL https://tinyjs.app/install | sh
#
# Downloads the latest release (or TINYJS_VERSION=vX.Y.Z) into ~/.tinyjs
# and symlinks the `tinyjs` CLI onto your PATH.
set -e

REPO="tarwin/tinyjsapp"
INSTALL_DIR="${TINYJS_HOME:-$HOME/.tinyjs}"
VERSION="${TINYJS_VERSION:-latest}"

OS="$(uname -s)"
case "$OS" in
  Darwin) PLAT=macos ;;
  Linux)  PLAT=linux ;;
  *) echo "tinyjs supports macOS and Linux (Windows: irm https://tinyjs.app/install.ps1 | iex)" >&2
     exit 1 ;;
esac

case "$(uname -m)" in
  arm64|aarch64) ARCH=arm64 ;;
  x86_64)        ARCH=x86_64 ;;
  *) echo "unsupported architecture: $(uname -m)" >&2; exit 1 ;;
esac

# Linux runs the system WebKitGTK — check it's there before downloading.
# ldconfig is only reachable via $PATH, and sbin usually isn't on a normal
# user's PATH (openSUSE keeps it in /usr/sbin), which made this check report
# a false miss there. Try the direct paths too, then pkg-config, then the
# library file for systems with no ldconfig at all.
HAVE_WEBKIT=""
if [ "$PLAT" = linux ]; then
  for ldc in ldconfig /sbin/ldconfig /usr/sbin/ldconfig; do
    "$ldc" -p 2>/dev/null | grep -q libwebkit2gtk-4.1 && { HAVE_WEBKIT=1; break; }
  done
  if [ -z "$HAVE_WEBKIT" ] && command -v pkg-config >/dev/null 2>&1 &&
     pkg-config --exists webkit2gtk-4.1 2>/dev/null; then
    HAVE_WEBKIT=1
  fi
  if [ -z "$HAVE_WEBKIT" ]; then
    for d in /usr/lib /usr/lib64 /usr/lib/*-linux-gnu; do
      ls "$d"/libwebkit2gtk-4.1.so* >/dev/null 2>&1 && { HAVE_WEBKIT=1; break; }
    done
  fi
fi
if [ "$PLAT" = linux ] && [ -z "$HAVE_WEBKIT" ]; then
  echo "tinyjs needs the WebKitGTK runtime." >&2
  echo "  Debian/Ubuntu:  sudo apt install libwebkit2gtk-4.1-0" >&2
  echo "  Fedora:         sudo dnf install webkit2gtk4.1" >&2
  echo "  Arch:           sudo pacman -S webkit2gtk-4.1" >&2
  echo "  openSUSE:       sudo zypper install libwebkit2gtk-4_1-0" >&2
  echo "then re-run this installer." >&2
  exit 1
fi

if [ "$VERSION" = "latest" ]; then
  VERSION=$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" |
    grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')
  [ -n "$VERSION" ] || { echo "could not determine latest release" >&2; exit 1; }
fi

ASSET="tinyjs-$PLAT-$ARCH.tar.gz"
URL="https://github.com/$REPO/releases/download/$VERSION/$ASSET"
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT

echo "==> downloading tinyjs $VERSION ($ARCH)"
curl -fsSL -o "$TMP/$ASSET" "$URL"

echo "==> verifying checksum"
curl -fsSL -o "$TMP/checksums.txt" \
  "https://github.com/$REPO/releases/download/$VERSION/checksums.txt"
if command -v shasum >/dev/null 2>&1; then SHACMD="shasum -a 256"; else SHACMD="sha256sum"; fi
(cd "$TMP" && grep " $ASSET\$" checksums.txt | $SHACMD -c - > /dev/null) ||
  { echo "checksum verification FAILED" >&2; exit 1; }

echo "==> installing to $INSTALL_DIR"
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"
tar -xzf "$TMP/$ASSET" -C "$INSTALL_DIR" --strip-components 1

# Clear quarantine on the binaries (curl doesn't set it, but belt & braces).
[ "$PLAT" = macos ] && xattr -dr com.apple.quarantine "$INSTALL_DIR" 2>/dev/null || true

# Symlink onto PATH. Prefer a writable dir that is ALREADY on PATH
# (/usr/local/bin, or /opt/homebrew/bin on Apple Silicon brew setups);
# fall back to ~/.local/bin, which usually needs a PATH edit.
BIN_DIR=""
for d in /usr/local/bin /opt/homebrew/bin; do
  case ":$PATH:" in *":$d:"*) ;; *) continue ;; esac
  if [ -d "$d" ] && [ -w "$d" ]; then BIN_DIR="$d"; break; fi
done
if [ -z "$BIN_DIR" ]; then
  BIN_DIR="$HOME/.local/bin"
  mkdir -p "$BIN_DIR"
fi
ln -sf "$INSTALL_DIR/tinyjs" "$BIN_DIR/tinyjs"

echo "==> installed: $("$INSTALL_DIR/tinyjs" version 2>/dev/null || echo tinyjs $VERSION)"
echo "    linked $BIN_DIR/tinyjs -> $INSTALL_DIR/tinyjs"

case ":$PATH:" in
  *":$BIN_DIR:"*)
    # BIN_DIR was picked precisely because it's already on PATH, so tinyjs is
    # ready — but a running shell caches command lookups, so this same terminal
    # can still say "command not found" until its hash table is refreshed.
    echo "    ($BIN_DIR is already on your PATH — a good home for it)"
    echo ""
    echo "If this terminal says \`tinyjs: command not found\`, run \`hash -r\`"
    echo "(or just open a new terminal) so your shell sees the new command."
    echo ""
    echo "get started:  tinyjs new myapp && cd myapp && tinyjs dev"
    ;;
  *)
    # BIN_DIR is not on PATH: offer to fix the shell profile, or shout.
    EXPORT_LINE="export PATH=\"$BIN_DIR:\$PATH\""
    PROFILE=""
    case "$(basename "${SHELL:-}")" in
      zsh)  PROFILE="$HOME/.zshrc" ;;
      bash) PROFILE="$HOME/.bashrc" ;;
      fish) PROFILE="$HOME/.config/fish/config.fish"
            EXPORT_LINE="fish_add_path $BIN_DIR" ;;
    esac

    # TINYJS_MODIFY_PATH=1 forces yes (scripted installs); TINYJS_NO_MODIFY_PATH=1
    # forces no; otherwise ask on the terminal when there is one.
    want=ask
    [ -n "$TINYJS_MODIFY_PATH" ] && want=yes
    [ -n "$TINYJS_NO_MODIFY_PATH" ] && want=no
    [ -z "$PROFILE" ] && want=no
    if [ "$want" = ask ]; then
      if printf "\n%s is not on your PATH. Add it to %s? [Y/n] " "$BIN_DIR" "$PROFILE" > /dev/tty 2>/dev/null &&
         read -r reply < /dev/tty 2>/dev/null; then
        case "$reply" in [nN]*) want=no ;; *) want=yes ;; esac
      else
        want=no
      fi
    fi

    if [ -t 1 ]; then
      RED=$(printf '\033[1;31m'); YELLOW=$(printf '\033[1;33m'); OFF=$(printf '\033[0m')
    else
      RED=""; YELLOW=""; OFF=""
    fi

    echo ""
    if [ "$want" = yes ]; then
      if ! grep -qs "added by tinyjs installer" "$PROFILE"; then
        mkdir -p "$(dirname "$PROFILE")"
        printf '\n# added by tinyjs installer\n%s\n' "$EXPORT_LINE" >> "$PROFILE"
      fi
      echo "${YELLOW}Added $BIN_DIR to your PATH in $PROFILE.${OFF}"
      echo "${YELLOW}Open a NEW terminal (or run the line below) before using tinyjs:${OFF}"
      echo ""
      echo "  $EXPORT_LINE"
    else
      echo "${RED}ACTION NEEDED: \`tinyjs\` will NOT work yet.${OFF}"
      echo "${RED}$BIN_DIR is not on your PATH. Add it to your shell profile${PROFILE:+ ($PROFILE)}:${OFF}"
      echo ""
      echo "  $EXPORT_LINE"
      echo ""
      echo "then open a new terminal."
    fi
    echo ""
    echo "get started (in a new terminal):  tinyjs new myapp && cd myapp && tinyjs dev"
    ;;
esac
