#!/bin/sh
# Instala la CLI de Shark (Linux y macOS, amd64 y arm64).
#
#   curl -fsSL https://dl.sharkmagic.si/install.sh | sh
#
# Detecta el sistema y la CPU, lee https://dl.sharkmagic.si/latest.json, descarga el binario versionado que ese
# documento nombra y comprueba su SHA-256 antes de instalar. Si algo no cuadra, no instala nada.
#
# Ajustes (variables de entorno):
#   SHARK_INSTALL_DIR=/ruta/bin   donde instalar (por defecto /usr/local/bin como root, si no ~/.local/bin)
#   SHARK_VERSION=0.2.0           fija la version, solo si es la actual
#   SHARK_DL_URL=https://...      espejo con el mismo formato (solo https; http/file solo en esta maquina)
set -eu

die() {
  printf 'shark install: %s\n' "$1" >&2
  printf 'next: revisa el error de arriba; no se instalo nada. Ayuda: https://sharkmagic.si/docs/\n' >&2
  exit 1
}

fetch() { # fetch <url> <destino>
  if command -v curl >/dev/null 2>&1; then
    curl -fsSL --retry 3 -o "$2" "$1" || die "no se pudo descargar $1"
  elif command -v wget >/dev/null 2>&1; then
    wget -q -O "$2" "$1" || die "no se pudo descargar $1"
  else
    die "hace falta curl o wget"
  fi
}

sha256_of() {
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$1" | awk '{print $1}'
  elif command -v shasum >/dev/null 2>&1; then
    shasum -a 256 "$1" | awk '{print $1}'
  elif command -v openssl >/dev/null 2>&1; then
    openssl dgst -sha256 "$1" | awk '{print $NF}'
  else
    die "hace falta sha256sum, shasum u openssl para verificar la descarga"
  fi
}

main() {
  base=${SHARK_DL_URL:-https://dl.sharkmagic.si}
  base=${base%/}
  case "$base" in
    https://*) ;;
    http://127.0.0.1[:/]* | http://localhost[:/]* | file://*) ;;
    *) die "SHARK_DL_URL tiene que ser https:// (http:// y file:// solo en esta maquina)" ;;
  esac

  case "$(uname -s)" in
    Linux) os=linux ;;
    Darwin) os=darwin ;;
    *)
      die "sistema no soportado: $(uname -s). Hay binarios para linux-amd64, linux-arm64, darwin-amd64 y darwin-arm64. Windows no esta soportado."
      ;;
  esac
  case "$(uname -m)" in
    x86_64 | amd64) arch=amd64 ;;
    aarch64 | arm64) arch=arm64 ;;
    *)
      die "CPU no soportada: $(uname -m). Hay binarios para linux-amd64, linux-arm64, darwin-amd64 y darwin-arm64."
      ;;
  esac
  asset="shark-$os-$arch"
  key="$os-$arch"

  if [ -n "${SHARK_INSTALL_DIR:-}" ]; then
    dir=$SHARK_INSTALL_DIR
  elif [ "$(id -u)" = 0 ]; then
    dir=/usr/local/bin
  else
    [ -n "${HOME:-}" ] || die "HOME no esta definido; usa SHARK_INSTALL_DIR"
    dir=$HOME/.local/bin
  fi

  tmp=$(mktemp -d 2>/dev/null || mktemp -d -t shark)
  trap 'rm -rf "$tmp"' EXIT
  trap 'exit 1' HUP INT TERM

  fetch "$base/latest.json" "$tmp/latest.json"
  version=$(sed -n 's/^[[:space:]]*"version":[[:space:]]*"\([^"]*\)".*/\1/p' "$tmp/latest.json" | head -1)
  [ -n "$version" ] || die "latest.json no trae version"
  if [ -n "${SHARK_VERSION:-}" ]; then
    pin=${SHARK_VERSION#v}
    [ "$pin" = "$version" ] || die "SHARK_VERSION=$pin no es la version publicada ($version); solo se sirve la actual"
  fi

  line=$(grep -F "\"$key\":" "$tmp/latest.json" | head -1)
  [ -n "$line" ] || die "latest.json no ofrece $key (soportados: linux-amd64, linux-arm64, darwin-amd64, darwin-arm64)"
  url=$(printf '%s' "$line" | sed -n 's/.*"url":[[:space:]]*"\([^"]*\)".*/\1/p')
  want=$(printf '%s' "$line" | sed -n 's/.*"sha256":[[:space:]]*"\([0-9a-f]\{64\}\)".*/\1/p')
  [ -n "$url" ] || die "latest.json no trae url para $asset"
  [ -n "$want" ] || die "latest.json no trae un sha256 valido para $asset"
  case "$url" in
    "$base"/releases/*) ;;
    *) die "url inesperada para $asset: $url" ;;
  esac

  printf 'shark install: bajando %s\n' "$asset" >&2
  fetch "$url" "$tmp/$asset"
  have=$(sha256_of "$tmp/$asset")
  if [ "$want" != "$have" ]; then
    rm -f "$tmp/$asset"
    die "checksum no coincide para $asset (esperado $want, obtenido $have)"
  fi
  printf 'shark install: sha256 %s verificado\n' "$have" >&2

  mkdir -p "$dir" || die "no se pudo crear $dir (usa SHARK_INSTALL_DIR)"
  [ -w "$dir" ] || die "$dir no es escribible (usa SHARK_INSTALL_DIR, por ejemplo \$HOME/.local/bin)"
  chmod 0755 "$tmp/$asset"
  cp "$tmp/$asset" "$dir/.shark.new.$$"
  mv -f "$dir/.shark.new.$$" "$dir/shark"
  printf 'shark install: instalado en %s/shark\n' "$dir" >&2
  printf 'shark install: %s\n' "$("$dir/shark" version 2>/dev/null || echo "shark $version")" >&2
  case ":${PATH:-}:" in
    *":$dir:"*) ;;
    *) printf 'shark install: %s no esta en PATH; anadelo:\n  export PATH="%s:$PATH"\n' "$dir" "$dir" >&2 ;;
  esac
  printf 'next: shark login\n' >&2
}

main "$@"
