#!/usr/bin/env bash
set -euo pipefail

export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH:-}"

SUPPORT_USER="${NVR_SUPPORT_USER:-nvr-setup}"
SUPPORT_KEY="${NVR_SUPPORT_AUTHORIZED_KEY:-}"
TTL_MINUTES="${NVR_SUPPORT_TTL_MINUTES:-240}"
ALLOW_CIDRS="${NVR_SUPPORT_ALLOWED_CIDRS:-192.168.0.0/16,10.0.0.0/8,172.16.0.0/12}"
STATE_DIR="${NVR_SUPPORT_STATE_DIR:-/var/lib/nvr/support}"
LOG_FILE="${NVR_SUPPORT_LOG_FILE:-/var/log/nvr/support-unlock.log}"
SSHD_DROPIN="/etc/ssh/sshd_config.d/90-nvr-support-unlock.conf"
SUDOERS_FILE="/etc/sudoers.d/90-nvr-support-unlock"
LOCKDOWN_BIN="/usr/local/sbin/nvr-support-lockdown"
CHANGED_SUPPORT=0
SUCCESS=0

fail() {
  printf 'nvr-support-unlock: erro: %s\n' "$*" >&2
  exit 1
}

log() {
  printf '[nvr-support-unlock] %s\n' "$*"
}

cleanup_on_failure() {
  local status="$?"
  if [ "$SUCCESS" != "1" ] && [ "$CHANGED_SUPPORT" = "1" ]; then
    if [ -x "$LOCKDOWN_BIN" ]; then
      "$LOCKDOWN_BIN" >/dev/null 2>&1 || true
    else
      rm -f "$SUDOERS_FILE" "$SSHD_DROPIN" "$STATE_DIR/authorized_key" "$STATE_DIR/key_inserted" 2>/dev/null || true
      systemctl reload ssh.service >/dev/null 2>&1 \
        || systemctl reload ssh >/dev/null 2>&1 \
        || systemctl reload sshd >/dev/null 2>&1 \
        || true
    fi
  fi
  exit "$status"
}

trap cleanup_on_failure EXIT

require_root() {
  [ "$(id -u)" -eq 0 ] || fail "execute com sudo/root"
}

normalize_ttl() {
  case "$TTL_MINUTES" in
    ''|*[!0-9]*)
      TTL_MINUTES=240
      ;;
  esac

  if [ "$TTL_MINUTES" -lt 15 ]; then
    TTL_MINUTES=15
  fi
  if [ "$TTL_MINUTES" -gt 720 ]; then
    TTL_MINUTES=720
  fi
}

read_key_from_stdin_if_needed() {
  if [ -n "$SUPPORT_KEY" ]; then
    return
  fi

  if [ ! -t 0 ]; then
    SUPPORT_KEY="$(sed -n '1p' | tr -d '\r' || true)"
  fi
}

validate_key() {
  SUPPORT_KEY="$(printf '%s' "$SUPPORT_KEY" | sed -E 's/[[:space:]]+$//')"
  [ -n "$SUPPORT_KEY" ] || fail "informe NVR_SUPPORT_AUTHORIZED_KEY ou envie a chave publica via stdin"

  case "$SUPPORT_KEY" in
    ssh-ed25519\ *|ssh-rsa\ *|ecdsa-sha2-nistp256\ *|ecdsa-sha2-nistp384\ *|ecdsa-sha2-nistp521\ *)
      ;;
    *)
      fail "chave publica SSH invalida"
      ;;
  esac
}

key_fingerprint() {
  if command -v ssh-keygen >/dev/null 2>&1; then
    printf '%s\n' "$SUPPORT_KEY" | ssh-keygen -lf - 2>/dev/null | awk '{print $2}' || true
  fi
}

set_unknown_password_hash_if_locked() {
  local status random password_hash

  command -v passwd >/dev/null 2>&1 || return 0
  status="$(passwd -S "$SUPPORT_USER" 2>/dev/null | awk '{print $2}' || true)"
  [ "$status" = "L" ] || return 0
  command -v openssl >/dev/null 2>&1 || return 0

  random="$(date +%s%N)-$(hostname 2>/dev/null || printf nvr)-$RANDOM"
  password_hash="$(openssl passwd -6 "$random" 2>/dev/null || true)"
  [ -n "$password_hash" ] || return 0
  usermod -p "$password_hash" "$SUPPORT_USER" 2>/dev/null || true
}

ensure_user() {
  if ! id "$SUPPORT_USER" >/dev/null 2>&1; then
    useradd -m -s /bin/bash "$SUPPORT_USER"
  else
    usermod -s /bin/bash "$SUPPORT_USER" 2>/dev/null || true
  fi

  set_unknown_password_hash_if_locked
  if command -v chage >/dev/null 2>&1; then
    chage -E -1 -I -1 -d "$(date +%Y-%m-%d)" "$SUPPORT_USER" 2>/dev/null || true
  fi
}

install_authorized_key() {
  local home_dir ssh_dir authorized_keys inserted previous_key previous_inserted
  CHANGED_SUPPORT=1

  home_dir="$(getent passwd "$SUPPORT_USER" | cut -d: -f6)"
  [ -n "$home_dir" ] || fail "home do usuario tecnico nao encontrado"

  ssh_dir="$home_dir/.ssh"
  authorized_keys="$ssh_dir/authorized_keys"
  install -d -o "$SUPPORT_USER" -g "$SUPPORT_USER" -m 0700 "$ssh_dir"
  touch "$authorized_keys"
  chown "$SUPPORT_USER:$SUPPORT_USER" "$authorized_keys"
  chmod 0600 "$authorized_keys"

  install -d -m 0700 -o root -g root "$STATE_DIR"
  previous_key="$(sed -n '1p' "$STATE_DIR/authorized_key" 2>/dev/null || true)"
  previous_inserted="$(sed -n '1p' "$STATE_DIR/key_inserted" 2>/dev/null || true)"
  inserted=0

  if ! grep -Fxq "$SUPPORT_KEY" "$authorized_keys"; then
    printf '%s\n' "$SUPPORT_KEY" >>"$authorized_keys"
    inserted=1
  elif [ "$previous_key" = "$SUPPORT_KEY" ] && [ "$previous_inserted" = "1" ]; then
    inserted=1
  fi

  printf '%s\n' "$SUPPORT_KEY" >"$STATE_DIR/authorized_key"
  printf '%s\n' "$inserted" >"$STATE_DIR/key_inserted"
  chmod 0600 "$STATE_DIR/authorized_key"
  chmod 0600 "$STATE_DIR/key_inserted"
}

install_sudoers() {
  CHANGED_SUPPORT=1
  printf '%s ALL=(ALL) NOPASSWD:ALL\n' "$SUPPORT_USER" >"$SUDOERS_FILE"
  chown root:root "$SUDOERS_FILE"
  chmod 0440 "$SUDOERS_FILE"

  if command -v visudo >/dev/null 2>&1; then
    visudo -cf "$SUDOERS_FILE" >/dev/null
  fi
}

configure_sshd() {
  local unit started reloaded effective_config
  CHANGED_SUPPORT=1

  install -d -m 0755 /etc/ssh/sshd_config.d
  install -d -m 0755 /run/sshd 2>/dev/null || true
  cat >"$SSHD_DROPIN" <<'EOF'
# NVR temporary support mode. Key-only remote maintenance.
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
EOF
  chown root:root "$SSHD_DROPIN"
  chmod 0644 "$SSHD_DROPIN"

  if command -v sshd >/dev/null 2>&1; then
    sshd -t
    effective_config="$(sshd -T 2>/dev/null || true)"
    printf '%s\n' "$effective_config" | grep -Eq '^pubkeyauthentication yes$' \
      || fail "configuracao efetiva do SSH nao habilitou chave publica"
    printf '%s\n' "$effective_config" | grep -Eq '^passwordauthentication no$' \
      || fail "configuracao efetiva do SSH nao bloqueou senha"
    printf '%s\n' "$effective_config" | grep -Eq '^permitrootlogin no$' \
      || fail "configuracao efetiva do SSH nao bloqueou root"
  else
    fail "servidor SSH nao encontrado"
  fi

  started=0
  for unit in ssh.service sshd.service ssh; do
    if systemctl enable --now "$unit" >/dev/null 2>&1; then
      started=1
      break
    fi
  done
  [ "$started" = "1" ] || fail "nao foi possivel iniciar o servico SSH"

  reloaded=0
  for unit in ssh.service sshd.service ssh; do
    if systemctl reload "$unit" >/dev/null 2>&1 || systemctl restart "$unit" >/dev/null 2>&1; then
      reloaded=1
      break
    fi
  done
  [ "$reloaded" = "1" ] || fail "nao foi possivel recarregar o servico SSH"
}

configure_firewall() {
  command -v ufw >/dev/null 2>&1 || return 0
  ufw status 2>/dev/null | grep -qi 'Status: active' || return 0

  local cidr
  IFS=',' read -r -a cidrs <<<"$ALLOW_CIDRS"
  for cidr in "${cidrs[@]}"; do
    cidr="$(printf '%s' "$cidr" | xargs)"
    [ -n "$cidr" ] || continue
    ufw allow from "$cidr" to any port 22 proto tcp comment 'NVR temporary support SSH' >/dev/null 2>&1 || true
  done
}

install_lockdown() {
  CHANGED_SUPPORT=1
  cat >"$LOCKDOWN_BIN" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

SUPPORT_USER="${NVR_SUPPORT_USER:-nvr-setup}"
STATE_DIR="${NVR_SUPPORT_STATE_DIR:-/var/lib/nvr/support}"
SSHD_DROPIN="/etc/ssh/sshd_config.d/90-nvr-support-unlock.conf"
SUDOERS_FILE="/etc/sudoers.d/90-nvr-support-unlock"

home_dir="$(getent passwd "$SUPPORT_USER" | cut -d: -f6 || true)"
key_file="$STATE_DIR/authorized_key"
inserted_file="$STATE_DIR/key_inserted"
if [ -n "$home_dir" ] && [ -f "$key_file" ] && [ -f "$home_dir/.ssh/authorized_keys" ] && [ "$(sed -n '1p' "$inserted_file" 2>/dev/null || true)" = "1" ]; then
  key="$(sed -n '1p' "$key_file")"
  if [ -n "$key" ]; then
    tmp_file="$(mktemp)"
    awk -v key="$key" '$0 != key { print }' "$home_dir/.ssh/authorized_keys" >"$tmp_file"
    cat "$tmp_file" >"$home_dir/.ssh/authorized_keys"
    rm -f "$tmp_file"
    chown "$SUPPORT_USER:$SUPPORT_USER" "$home_dir/.ssh/authorized_keys" 2>/dev/null || true
    chmod 0600 "$home_dir/.ssh/authorized_keys" 2>/dev/null || true
  fi
fi

rm -f "$SUDOERS_FILE" "$SSHD_DROPIN"
rm -f "$STATE_DIR/authorized_key" "$STATE_DIR/key_inserted"

systemctl reload ssh.service >/dev/null 2>&1 \
  || systemctl reload ssh >/dev/null 2>&1 \
  || systemctl reload sshd >/dev/null 2>&1 \
  || true

systemctl reset-failed nvr-support-lockdown.service >/dev/null 2>&1 || true
printf 'nvr-support-lockdown=ok\n'
EOF
  chmod 0755 "$LOCKDOWN_BIN"
}

schedule_lockdown() {
  systemctl stop nvr-support-lockdown.timer nvr-support-lockdown.service >/dev/null 2>&1 || true
  systemctl reset-failed nvr-support-lockdown.service >/dev/null 2>&1 || true
  systemctl reset-failed nvr-support-lockdown.timer >/dev/null 2>&1 || true
  systemd-run --unit=nvr-support-lockdown --on-active="${TTL_MINUTES}m" "$LOCKDOWN_BIN" >/dev/null 2>&1 \
    || fail "nao foi possivel agendar lockdown automatico"
}

write_evidence() {
  install -d -m 0750 -o root -g root "$(dirname "$LOG_FILE")"
  {
    printf 'support_unlocked_at=%s\n' "$(date -Is)"
    printf 'support_user=%s\n' "$SUPPORT_USER"
    printf 'support_key_fingerprint=%s\n' "$(key_fingerprint)"
    printf 'ttl_minutes=%s\n' "$TTL_MINUTES"
    printf 'password_authentication=no\n'
    printf 'root_login=no\n'
    printf 'sudo_nopasswd=yes\n'
  } | tee -a "$LOG_FILE" >/dev/null
  chmod 0640 "$LOG_FILE" 2>/dev/null || true
}

print_summary() {
  local ip
  ip="$(hostname -I 2>/dev/null | awk '{print $1}')"
  printf 'support_unlock=ok\n'
  printf 'support_user=%s\n' "$SUPPORT_USER"
  printf 'support_key_fingerprint=%s\n' "$(key_fingerprint)"
  printf 'ssh_host=%s\n' "${ip:-unknown}"
  printf 'ttl_minutes=%s\n' "$TTL_MINUTES"
  printf 'password_authentication=no\n'
  printf 'root_login=no\n'
  printf 'sudo_nopasswd=yes\n'
}

main() {
  require_root
  normalize_ttl
  read_key_from_stdin_if_needed
  validate_key
  ensure_user
  install_lockdown
  configure_sshd
  install_authorized_key
  install_sudoers
  configure_firewall
  schedule_lockdown
  write_evidence
  SUCCESS=1
  print_summary
}

main "$@"
