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

LAB_ROOT="${SORIA_LINUX_SYSTEMD_LAB:-/tmp/soria-linux-systemd-${USER:-$(id -un)}}"
MARKER="$LAB_ROOT/.soria-linux-systemd-lab"

usage() {
  cat <<'USAGE'
Usage: module4-systemd-boot-lab.sh {setup|status|validate|emit|reset}

The lab writes only below SORIA_LINUX_SYSTEMD_LAB. The path must remain under
/tmp or the current user's HOME. It never edits GRUB, installs a unit, reloads
systemd, changes the default target, or schedules a shutdown.
USAGE
}

is_safe_root() {
  case "$LAB_ROOT" in
    /tmp/soria-linux-systemd-*|"$HOME"/soria-linux-systemd-*) return 0 ;;
    *) return 1 ;;
  esac
}

require_safe_root() {
  is_safe_root || { printf 'Refusing unsafe lab path: %s\n' "$LAB_ROOT" >&2; exit 2; }
}

require_initialized() {
  [[ -f "$MARKER" ]] || { printf 'Lab not initialized: %s\n' "$LAB_ROOT" >&2; exit 1; }
}

write_boot_report() {
  {
    printf 'generated_at=%s\n' "$(date -u +%FT%TZ)"
    printf 'kernel=%s\n' "$(uname -r)"
    printf 'architecture=%s\n' "$(uname -m)"
    printf 'pid1_comm=%s\n' "$(ps -p 1 -o comm= 2>/dev/null || true)"
    printf 'pid1_exe=%s\n' "$(readlink -f /proc/1/exe 2>/dev/null || true)"
    printf 'kernel_cmdline='
    cat /proc/cmdline 2>/dev/null || true
    printf '\n'
    if command -v systemd >/dev/null 2>&1; then
      systemd --version | sed -n '1p'
    fi
    if command -v systemctl >/dev/null 2>&1; then
      printf 'default_target=%s\n' "$(systemctl get-default 2>/dev/null || echo unavailable)"
    fi
  } > "$LAB_ROOT/reports/boot-readonly.txt"
}

setup_lab() {
  require_safe_root
  if [[ -e "$LAB_ROOT" && ! -f "$MARKER" ]]; then
    printf 'Refusing existing unmarked directory: %s\n' "$LAB_ROOT" >&2
    exit 2
  fi

  mkdir -p "$LAB_ROOT"/{bin,config,grub,logs,reports,units,broken,home}
  : > "$MARKER"

  cat > "$LAB_ROOT/bin/soria-agent.sh" <<'WORKER'
#!/usr/bin/env bash
set -euo pipefail
mode="${1:-once}"
agent_name="${AGENT_NAME:-soria-agent}"
interval="${INTERVAL_SECONDS:-1}"

printf 'agent=%s pid=%s mode=%s event=start\n' "$agent_name" "$$" "$mode"
printf 'agent=%s level=warning message=training-warning\n' "$agent_name" >&2

case "$mode" in
  once)
    sleep "$interval"
    printf 'agent=%s event=complete\n' "$agent_name"
    ;;
  fail)
    printf 'agent=%s level=error message=simulated-failure\n' "$agent_name" >&2
    exit 23
    ;;
  *)
    printf 'unsupported mode: %s\n' "$mode" >&2
    exit 2
    ;;
esac
WORKER

  cat > "$LAB_ROOT/config/soria-agent.env" <<'ENVFILE'
AGENT_NAME=soria-lab-agent
INTERVAL_SECONDS=1
ENVFILE

  cat > "$LAB_ROOT/grub/default-grub.sample" <<'GRUBDEFAULT'
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX=""
GRUBDEFAULT

  cat > "$LAB_ROOT/grub/grub.cfg.sample" <<'GRUBCFG'
set timeout=5
menuentry 'SORIA Linux training entry' {
    linux /vmlinuz root=/dev/mapper/vg-root ro quiet
    initrd /initrd.img
}
GRUBCFG

  cat > "$LAB_ROOT/home/profile.sample" <<'PROFILE'
export SORIA_ENV=login
export PATH="$HOME/.local/bin:$PATH"
PROFILE

  cat > "$LAB_ROOT/home/bashrc.sample" <<'BASHRC'
export SORIA_INTERACTIVE=interactive
alias ll='ls -alF'
BASHRC

  cat > "$LAB_ROOT/units/soria-agent.service" <<EOF_UNIT
[Unit]
Description=SORIA training agent
Documentation=https://soria-academie.fr
ConditionPathExists=$LAB_ROOT/config/soria-agent.env

[Service]
Type=oneshot
EnvironmentFile=$LAB_ROOT/config/soria-agent.env
ExecStart=$LAB_ROOT/bin/soria-agent.sh once
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=default.target
EOF_UNIT

  cat > "$LAB_ROOT/units/soria-agent-failing.service" <<EOF_FAIL
[Unit]
Description=SORIA deliberately failing training agent
ConditionPathExists=$LAB_ROOT/config/soria-agent.env

[Service]
Type=oneshot
EnvironmentFile=$LAB_ROOT/config/soria-agent.env
ExecStart=$LAB_ROOT/bin/soria-agent.sh fail
StandardOutput=journal
StandardError=journal
EOF_FAIL

  cat > "$LAB_ROOT/units/soria-lab.target" <<'EOF_TARGET'
[Unit]
Description=SORIA Linux laboratory target
Wants=soria-agent.service
After=soria-agent.service
EOF_TARGET

  cat > "$LAB_ROOT/broken/soria-agent-broken.service" <<'EOF_BROKEN'
[Unit]
Description=SORIA broken unit for diagnosis

[Service]
Type=oneshot
ExecStart=relative/path/is/not/allowed
RestartSec=not-a-duration
EOF_BROKEN

  chmod 0755 "$LAB_ROOT/bin/soria-agent.sh"
  chmod 0644 "$LAB_ROOT/config/soria-agent.env" "$LAB_ROOT/grub/"* \
    "$LAB_ROOT/home/"* "$LAB_ROOT/units/"* "$LAB_ROOT/broken/"*

  write_boot_report
  printf 'Lab ready: %s\n' "$LAB_ROOT"
}

show_status() {
  require_safe_root
  require_initialized
  write_boot_report

  printf 'Lab root: %s\n\n' "$LAB_ROOT"
  cat "$LAB_ROOT/reports/boot-readonly.txt"

  printf '\nPrepared unit files:\n'
  find "$LAB_ROOT/units" -maxdepth 1 -type f -printf '%f\n' | sort

  printf '\nPrepared GRUB copies:\n'
  find "$LAB_ROOT/grub" -maxdepth 1 -type f -printf '%f\n' | sort
}

validate_lab() {
  require_safe_root
  require_initialized

  bash -n "$LAB_ROOT/bin/soria-agent.sh"
  grep -q '^ExecStart=/' "$LAB_ROOT/units/soria-agent.service"
  grep -q '^WantedBy=default.target$' "$LAB_ROOT/units/soria-agent.service"
  grep -q '^Wants=soria-agent.service$' "$LAB_ROOT/units/soria-lab.target"

  if command -v systemd-analyze >/dev/null 2>&1; then
    systemd-analyze verify \
      "$LAB_ROOT/units/soria-agent.service" \
      "$LAB_ROOT/units/soria-agent-failing.service" \
      "$LAB_ROOT/units/soria-lab.target"

    if systemd-analyze verify "$LAB_ROOT/broken/soria-agent-broken.service" \
      > "$LAB_ROOT/logs/broken-unit-verify.log" 2>&1; then
      printf 'Broken unit unexpectedly passed validation\n' >&2
      exit 1
    fi
  else
    printf 'systemd-analyze unavailable; structural checks only.\n'
  fi

  if command -v grub-script-check >/dev/null 2>&1; then
    grub-script-check "$LAB_ROOT/grub/grub.cfg.sample"
  else
    printf 'grub-script-check unavailable; GRUB sample not syntax-checked.\n'
  fi

  printf 'Validation completed successfully.\n'
}

emit_demo() {
  require_safe_root
  require_initialized
  set -a
  # shellcheck disable=SC1090
  . "$LAB_ROOT/config/soria-agent.env"
  set +a

  "$LAB_ROOT/bin/soria-agent.sh" once \
    > "$LAB_ROOT/logs/agent.stdout.log" \
    2> "$LAB_ROOT/logs/agent.stderr.log"

  if command -v systemd-cat >/dev/null 2>&1 && [[ -S /run/systemd/journal/socket ]]; then
    {
      cat "$LAB_ROOT/logs/agent.stdout.log"
      cat "$LAB_ROOT/logs/agent.stderr.log" >&2
    } | systemd-cat -t soria-linux-lab
    printf 'Demo also submitted to journald with identifier soria-linux-lab.\n'
  else
    printf 'journald socket unavailable; file logs only.\n'
  fi

  printf 'stdout=%s\nstderr=%s\n' \
    "$LAB_ROOT/logs/agent.stdout.log" "$LAB_ROOT/logs/agent.stderr.log"
}

reset_lab() {
  require_safe_root
  require_initialized
  rm -rf --one-file-system "$LAB_ROOT"
  printf 'Lab removed: %s\n' "$LAB_ROOT"
}

case "${1:-}" in
  setup) setup_lab ;;
  status) show_status ;;
  validate) validate_lab ;;
  emit) emit_demo ;;
  reset) reset_lab ;;
  *) usage; exit 2 ;;
esac
