#!/bin/sh
# Instalador do agente local do NeoLeaf (Linux x86_64 e macOS, sem sudo).
#
#   curl -fsSL https://neoleaf.science/install.sh | sh
#
# O que faz: baixa o agente de https://neoleaf.science, confere o SHA-256 publicado em version.json, copia para
# ~/.local/bin/neoleaf-agent e registra o serviço do seu usuário (systemd --user no Linux, LaunchAgent no macOS). Nada é instalado
# fora da sua pasta pessoal. Para ver o que ele faz antes de rodar: curl -fsSL https://neoleaf.science/install.sh | less
set -eu

SITE="${NEOLEAF_SITE:-https://neoleaf.science}"
SITE="${SITE%/}"

say() { printf '%s\n' "$*"; }
die() { printf 'Erro: %s\n' "$*" >&2; exit 1; }
have() { command -v "$1" >/dev/null 2>&1; }

os="$(uname -s)"
case "$os" in
  Linux)
    asset="neoleaf-agent-linux-x86_64"; hashkey="sha256"
    case "$(uname -m)" in
      x86_64 | amd64) ;;
      *) die "no Linux só há binário para x86_64 (esta máquina é $(uname -m))." ;;
    esac ;;
  Darwin)
    asset="neoleaf-agent-macos-universal"; hashkey="sha256_macos" ;;
  *) die "o agente só existe para Linux e macOS (este sistema é $os)." ;;
esac
[ "$(id -u)" != "0" ] || die "não rode como root: o agente é instalado para o seu usuário, sem sudo."

if have curl; then
  fetch() { curl -fsSL --retry 3 "$1" -o "$2"; }
elif have wget; then
  fetch() { wget -q -O "$2" "$1"; }
else
  die "precisa de curl ou wget."
fi

hash_of() {
  if have sha256sum; then
    sha256sum "$1" | cut -d' ' -f1
  elif have shasum; then
    shasum -a 256 "$1" | cut -d' ' -f1
  else
    die "precisa de sha256sum (ou shasum) para conferir o download."
  fi
}

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT INT TERM

say "Baixando o agente do NeoLeaf de $SITE ..."
fetch "$SITE/static/agent/version.json" "$tmp/version.json" || die "não consegui baixar $SITE/static/agent/version.json"
expected="$(sed -n 's/.*"'"$hashkey"'" *: *"\([0-9a-fA-F]\{64\}\)".*/\1/p' "$tmp/version.json" | head -n 1 | tr 'A-F' 'a-f')"
version="$(sed -n 's/.*"version" *: *"\([^"]*\)".*/\1/p' "$tmp/version.json" | head -n 1)"
[ -n "$expected" ] || die "não achei o SHA-256 em version.json: não vou instalar sem poder conferir."

fetch "$SITE/static/agent/$asset" "$tmp/neoleaf-agent" || die "não consegui baixar o agente."
actual="$(hash_of "$tmp/neoleaf-agent")"
[ "$actual" = "$expected" ] || die "o SHA-256 do arquivo baixado não confere com o publicado. Nada foi instalado."
chmod +x "$tmp/neoleaf-agent"
# macOS (Apple Silicon) só executa binário assinado: assinatura ad hoc, local, sem conta de desenvolvedor
if [ "$os" = "Darwin" ]; then codesign --force --sign - "$tmp/neoleaf-agent" >/dev/null 2>&1 || true; fi
say "Agente ${version:-?} baixado e conferido (SHA-256)."

bin="$HOME/.local/bin/neoleaf-agent"
if ! "$tmp/neoleaf-agent" install; then
  say ""
  say "O agente foi copiado para $bin, mas não consegui registrar o serviço (o gerenciador de serviços do usuário não está disponível?)."
  say "Você pode rodá-lo à mão, em um terminal que fique aberto:"
  say "  $bin"
  exit 1
fi

# Sem compilador LaTeX na máquina? Oferece instalar o TinyTeX (pergunta no terminal, mesmo com o script vindo por pipe).
if "$bin" engines 2>/dev/null | grep -q "Nenhum compilador"; then
  say ""
  say "Esta máquina ainda não tem um compilador LaTeX (TeX Live, TinyTeX ou Tectonic)."
  if [ -r /dev/tty ] && [ -w /dev/tty ]; then
    printf 'Instalar o TinyTeX agora? [s/N] ' > /dev/tty
    answer=""
    read -r answer < /dev/tty || answer=""
    case "$answer" in
      s | S | sim | y | Y | yes) "$bin" install-tinytex --yes < /dev/tty || say "A instalação do TinyTeX falhou; tente depois: $bin install-tinytex" ;;
      *) say "Tudo bem. Quando quiser: $bin install-tinytex" ;;
    esac
  else
    say "Para instalar o TinyTeX: $bin install-tinytex"
  fi
fi

say ""
say "Pronto. Abra um projeto no NeoLeaf e escolha o motor \"Local\" no seletor de compilação."
say "Na primeira compilação o navegador pede o código de pareamento (o agente também o mostra numa notificação)."
say "Para gerar um código agora: $bin code"
