#!/usr/bin/env bash
# secrets-install.sh — instala (ou atualiza) o cofre num servidor que já existe.
#
# Servidor novo recebe o cofre no Dia Zero (create-ops-user.sh) e no
# provisionamento. Este script é para o servidor que passou por essas etapas
# numa versão anterior do SSHepherd, e também para reinstalar o helper depois
# de uma atualização do framework.
#
# Precisa de root no servidor, de um jeito ou de outro:
#   --user root      conecta como root (só funciona antes do endurecimento)
#   --user deploy    conecta como o usuário de operação e usa `sudo -n`; só
#                    funciona se esse usuário tiver sudo sem senha para bash,
#                    o que o SSHepherd NÃO concede. Se falhar, o caminho é o
#                    console do provedor: rode ali, como root, o comando que
#                    este script imprime com --print.
#
# Uso:
#   secrets-install.sh --host <ip> --user <root|deploy> [--port 22] [--key <chave>]
#                      [--ops deploy] [--app-path /srv/app] [--print]

set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
. "${SCRIPT_DIR}/vault-install.sh"

HOST=""; USER_NAME=""; PORT=22; KEY_PATH=""; OPS="deploy"; APP_PATH="/srv/app"; PRINT=0

while [ $# -gt 0 ]; do
  case "$1" in
    --host) HOST="$2"; shift 2 ;;
    --user) USER_NAME="$2"; shift 2 ;;
    --port) PORT="$2"; shift 2 ;;
    --key) KEY_PATH="$2"; shift 2 ;;
    --ops) OPS="$2"; shift 2 ;;
    --app-path) APP_PATH="$2"; shift 2 ;;
    --print) PRINT=1; shift ;;
    *) echo "argumento desconhecido: $1" >&2; exit 2 ;;
  esac
done

case "$OPS" in ""|root|*[!a-z0-9_-]*) echo "ERRO: --ops inválido: '${OPS}'" >&2; exit 2 ;; esac
case "$APP_PATH" in /*) ;; *) echo "ERRO: --app-path precisa ser caminho absoluto" >&2; exit 2 ;; esac
case "$APP_PATH" in *[!A-Za-z0-9._/-]*) echo "ERRO: --app-path com caractere inválido" >&2; exit 2 ;; esac

BLOCO=$(vault_install_block "$OPS" "$APP_PATH")

if [ "$PRINT" -eq 1 ]; then
  echo "# Rode como root no servidor (console do provedor serve):"
  printf '%s\n' "$BLOCO"
  exit 0
fi

[ -n "$HOST" ] || { echo "ERRO: --host é obrigatório (ou use --print)" >&2; exit 2; }
[ -n "$USER_NAME" ] || { echo "ERRO: --user é obrigatório" >&2; exit 2; }

SSH_OPTS=(-o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ForwardAgent=no -o ConnectTimeout=10 -p "$PORT")
[ -n "$KEY_PATH" ] && SSH_OPTS+=(-i "${KEY_PATH/#\~/$HOME}" -o IdentitiesOnly=yes)

echo "--------------------------------------------"
echo " COFRE DE SEGREDOS em ${HOST}"
echo "  usuário de operação : ${OPS}"
echo "  aplicação           : ${APP_PATH}"
echo "  conectando como     : ${USER_NAME}"
echo "--------------------------------------------"

if [ "$USER_NAME" = "root" ]; then
  OUT=$(ssh "${SSH_OPTS[@]}" "root@${HOST}" "bash -s" <<< "$BLOCO" 2>&1)
else
  OUT=$(ssh "${SSH_OPTS[@]}" "${USER_NAME}@${HOST}" "sudo -n bash -s" <<< "$BLOCO" 2>&1)
fi
CODE=$?
printf '%s\n' "$OUT"

if [ $CODE -eq 255 ]; then
  echo "FALHA DE CONEXAO com ${USER_NAME}@${HOST}:${PORT}" >&2
  exit 13
fi
if printf '%s' "$OUT" | grep -q "password is required"; then
  echo "" >&2
  echo "'${USER_NAME}' não tem sudo sem senha para instalar o cofre, e o SSHepherd não concede isso." >&2
  echo "Caminho: abra o console do provedor como root e cole o que este comando imprime:" >&2
  echo "  secrets-install.sh --ops ${OPS} --app-path ${APP_PATH} --print" >&2
  exit 14
fi
if ! printf '%s' "$OUT" | grep -q "^cofre_pronto=sim"; then
  echo "" >&2
  echo "A instalação do cofre não terminou (código ${CODE}). Leia a saída acima." >&2
  exit "${CODE:-4}"
fi
echo ""
echo "Cofre pronto. Próximo passo: /sshp-secrets"
exit 0
