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

readonly SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
readonly MARKER="${SCRIPT_DIR}/.sys-l-204-vm"
readonly ATTEMPT_FILE="${SCRIPT_DIR}/.attempt-id"
readonly GROUP_NAME="syslab_reports"
readonly WRITER="syslab_writer"
readonly READER="syslab_reader"

die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; }
validate_marker() {
  [[ -f "${MARKER}" ]] || die "falta marcador"
  [[ "$(cat "${MARKER}")" == "SYS-L-204 fixture v1" ]] || die "marcador inesperado"
}
attempt() {
  if [[ ! -f "${ATTEMPT_FILE}" ]]; then
    printf '%s-%s-%s\n' "$(date -u +%Y%m%dT%H%M%SZ)" "$$" "${RANDOM}" >"${ATTEMPT_FILE}"
  fi
  tr -cd 'A-Za-z0-9._-' <"${ATTEMPT_FILE}"
}
target_dir() { printf '/srv/sys-l-204-%s\n' "$(attempt)"; }
preflight() {
  validate_marker
  command -v getfacl >/dev/null 2>&1 || die "instala el paquete acl en la VM"
  command -v namei >/dev/null 2>&1 || die "se requiere namei"
  printf 'lab=SYS-L-204 attempt=%s target=%s\n' "$(attempt)" "$(target_dir)"
}
setup() {
  [[ "${EUID}" -eq 0 ]] || die "setup requiere sudo dentro de la VM"
  preflight
  ! getent group "${GROUP_NAME}" >/dev/null || die "el grupo ${GROUP_NAME} ya existe"
  ! getent passwd "${WRITER}" >/dev/null || die "el usuario ${WRITER} ya existe"
  ! getent passwd "${READER}" >/dev/null || die "el usuario ${READER} ya existe"
  local target id
  target="$(target_dir)"; id="$(attempt)"
  [[ "${target}" == "/srv/sys-l-204-${id}" ]] || die "target inesperado"
  groupadd --system "${GROUP_NAME}"
  useradd --system --no-create-home --shell /usr/sbin/nologin \
    --comment "SYS-L-204 ${id}" "${WRITER}"
  useradd --system --no-create-home --shell /usr/sbin/nologin \
    --comment "SYS-L-204 ${id}" "${READER}"
  usermod -a -G "${GROUP_NAME}" "${WRITER}"
  install -d -m 0710 -o root -g "${GROUP_NAME}" "${target}"
  install -d -m 0750 -o "${WRITER}" -g "${GROUP_NAME}" "${target}/reports"
  printf '%s\n' "${id}" >"${target}/.sys-l-204-attempt"
  chown root:"${GROUP_NAME}" "${target}/.sys-l-204-attempt"
  chmod 0640 "${target}/.sys-l-204-attempt"
  printf 'setup=complete target=%s\n' "${target}"
}
inspect_state() {
  preflight
  id "${WRITER}" 2>/dev/null || true
  id "${READER}" 2>/dev/null || true
  namei -l "$(target_dir)/reports" 2>/dev/null || true
  getfacl -p "$(target_dir)" "$(target_dir)/reports" 2>/dev/null || true
}
rollback() {
  [[ "${EUID}" -eq 0 ]] || die "rollback requiere sudo dentro de la VM"
  validate_marker
  local target id marker comment
  target="$(target_dir)"; id="$(attempt)"; marker="${target}/.sys-l-204-attempt"
  [[ "${target}" == "/srv/sys-l-204-${id}" ]] || die "target inesperado"
  [[ -f "${marker}" ]] || die "falta marcador del intento en target"
  [[ "$(cat "${marker}")" == "${id}" ]] || die "el target pertenece a otro intento"
  comment="$(getent passwd "${WRITER}" | cut -d: -f5)"
  [[ "${comment}" == "SYS-L-204 ${id}" ]] || die "identidad writer no validada"
  comment="$(getent passwd "${READER}" | cut -d: -f5)"
  [[ "${comment}" == "SYS-L-204 ${id}" ]] || die "identidad reader no validada"
  rm -f -- "${target}/reports/"*
  rm -f -- "${marker}"
  rmdir -- "${target}/reports" "${target}"
  userdel "${WRITER}"
  userdel "${READER}"
  groupdel "${GROUP_NAME}"
  printf 'rollback=complete\n'
}
case "${1:-}" in
  preflight) preflight ;;
  setup) setup ;;
  inspect) inspect_state ;;
  rollback) rollback ;;
  *) die "uso: ./lab {preflight|setup|inspect|rollback}" ;;
esac
