#!/usr/bin/env bash
# Mock `getent`. Not dangerous (a plain, read-only NSS lookup) but mocked
# anyway for determinism — a test asserting on ensure_group's branching must
# not depend on whether THIS machine happens to already have a
# `sonomos-proxy`/`sonomos-bypass` group, the same reasoning Locke's own
# `getent` mock documents.
#
# `getent group <name>` succeeds (and prints a fake /etc/group line) iff
# <name> is listed in $SONOMOS_TEST_GROUPS (colon-separated). Its gid is 65534
# unless $SONOMOS_TEST_GROUP_GIDS names one — SEMICOLON-separated "name|gid"
# records — which is what lets reset_uncovered_test.sh give the proxy and
# bypass groups the DIFFERENT gids its exclusion has to tell apart.
#
# `getent ahosts <host>` prints one line per address in the shape the real
# command does ("<addr>  STREAM <host>") for every address $SONOMOS_TEST_AHOSTS
# gives <host> — SEMICOLON-separated "host|addr addr…" records — and exits 2,
# like an unresolvable name, for a host it does not list. A host named in
# $SONOMOS_TEST_AHOSTS_HANG never answers at all (the stalled resolver the
# helper's per-lookup `timeout` exists for).
#
# `getent passwd <name>` succeeds (and prints a fake /etc/passwd line) iff
# <name> has an entry in $SONOMOS_TEST_PASSWD — SEMICOLON-separated records of
# "user|home|shell[|uid]" (a pipe, because a passwd line's own separator is a
# colon). The uid (and the gid, which mirrors it) is 1000 unless the record
# names one; `getent passwd <uid>` finds a record by that uid, as the real one
# does — first-time-setup resolves PKEXEC_UID that way. Absent or unlisted, it
# exits 2, which is exactly what a real `getent` does for a user NSS cannot
# resolve — the case linux.sh must refuse rather than guess.
if [ "$1" = "group" ] && [ -n "${2:-}" ]; then
  case ":${SONOMOS_TEST_GROUPS:-}:" in
    *":$2:"*)
      _gid=65534
      _saved_ifs="$IFS"
      IFS=';'
      for _rec in ${SONOMOS_TEST_GROUP_GIDS:-}; do
        [ "${_rec%%|*}" = "$2" ] && _gid="${_rec#*|}"
      done
      IFS="$_saved_ifs"
      echo "$2:x:$_gid:"
      exit 0 ;;
    *) exit 2 ;;
  esac
fi
if [ "$1" = "ahosts" ] && [ -n "${2:-}" ]; then
  if [ -n "${SONOMOS_TEST_AHOSTS_HANG:-}" ] && [ "$2" = "$SONOMOS_TEST_AHOSTS_HANG" ]; then
    exec sleep 30
  fi
  _saved_ifs="$IFS"
  IFS=';'
  for _rec in ${SONOMOS_TEST_AHOSTS:-}; do
    IFS="$_saved_ifs"
    if [ "${_rec%%|*}" = "$2" ]; then
      for _addr in ${_rec#*|}; do
        printf '%-24s STREAM %s\n' "$_addr" "$2"
      done
      exit 0
    fi
    IFS=';'
  done
  IFS="$_saved_ifs"
  exit 2
fi
if [ "$1" = "passwd" ] && [ -n "${2:-}" ]; then
  _saved_ifs="$IFS"
  IFS=';'
  for _rec in ${SONOMOS_TEST_PASSWD:-}; do
    IFS="$_saved_ifs"
    _u="${_rec%%|*}"; _rest="${_rec#*|}"
    _h="${_rest%%|*}"; _rest="${_rest#*|}"
    _s="${_rest%%|*}"; _uid=1000
    case "$_rest" in *"|"*) _uid="${_rest#*|}" ;; esac
    if [ "$_u" = "$2" ] || [ "$_uid" = "$2" ]; then
      echo "$_u:x:$_uid:$_uid:Mock User:$_h:$_s"
      exit 0
    fi
    IFS=';'
  done
  IFS="$_saved_ifs"
  exit 2
fi
exit 2
