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

readonly LAB_ID="SYS-L-202"
readonly LABEL_KEY="io.kiril-ferrer.learning.attempt"
readonly SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
readonly ATTEMPT_FILE="${SCRIPT_DIR}/.attempt-id"

die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; }
runtime() {
  if command -v podman >/dev/null 2>&1; then printf 'podman\n'; return; fi
  if command -v docker >/dev/null 2>&1; then printf 'docker\n'; return; fi
  die "se requiere Podman rootless, Docker rootless o Docker Desktop"
}
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}"
}
container_name() { printf 'sys-l-202-%s\n' "$(attempt)"; }
image_name() { printf 'sys-l-202:%s\n' "$(attempt)"; }
validate_target() {
  local actual
  actual="$("$(runtime)" inspect --format "{{ index .Config.Labels \"${LABEL_KEY}\" }}" "$(container_name)" 2>/dev/null || true)"
  [[ "${actual}" == "$(attempt)" ]] || die "el contenedor no pertenece a este intento"
}
preflight() {
  [[ "${EUID}" -ne 0 ]] || die "no ejecutes como root"
  "$(runtime)" info >/dev/null
  printf 'lab=%s runtime=%s attempt=%s\n' "${LAB_ID}" "$(runtime)" "$(attempt)"
}
start() {
  preflight
  local engine name image id
  engine="$(runtime)"; name="$(container_name)"; image="$(image_name)"; id="$(attempt)"
  if "${engine}" inspect "${name}" >/dev/null 2>&1; then validate_target; die "el intento ya existe"; fi
  "${engine}" build --tag "${image}" --file "${SCRIPT_DIR}/Containerfile" "${SCRIPT_DIR}"
  "${engine}" run --detach --name "${name}" --label "${LABEL_KEY}=${id}" \
    --pids-limit 64 --memory 128m --cpus 0.50 "${image}" >/dev/null
  printf 'started=%s\n' "${name}"
}
inspect_state() {
  validate_target
  "$(runtime)" exec "$(container_name)" sh -c '
    ps -eo pid,ppid,pgid,sid,state,ni,etimes,cmd
    printf "%s\n" "--- proc status ---"
    for pid in $(pgrep -f "/opt/sys-l-202/worker.py"); do
      grep -E "^(Name|State|Pid|PPid|Threads|SigPnd|SigBlk|SigIgn|SigCgt):" "/proc/${pid}/status"
      printf "%s\n" "--"
    done
  '
}
signal_role() {
  validate_target
  local action="${1:-}" role="${2:-}" signal
  case "${action}" in stop) signal=STOP ;; cont) signal=CONT ;; term) signal=TERM ;; *) die "señal permitida: stop, cont o term" ;; esac
  case "${role}" in worker-a|worker-b|worker-c) ;; *) die "rol desconocido" ;; esac
  "$(runtime)" exec "$(container_name)" sh -c \
    'pid="$(pgrep -f "worker.py '"${role}"'$" | head -n1)"; test -n "$pid"; kill -'"${signal}"' "$pid"; printf "role=%s pid=%s signal=%s\n" '"${role}"' "$pid" '"${signal}"
}
destroy() {
  validate_target
  local engine name image
  engine="$(runtime)"; name="$(container_name)"; image="$(image_name)"
  "${engine}" rm --force "${name}" >/dev/null
  "${engine}" image rm "${image}" >/dev/null 2>&1 || true
  printf 'destroyed=%s\n' "${name}"
}
reset() { destroy; start; }

case "${1:-}" in
  preflight) preflight ;;
  start) start ;;
  inspect) inspect_state ;;
  signal) signal_role "${2:-}" "${3:-}" ;;
  reset) reset ;;
  destroy) destroy ;;
  *) die "uso: ./lab {preflight|start|inspect|signal <stop|cont|term> <role>|reset|destroy}" ;;
esac
