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

readonly LAB_ID="SYS-L-201"
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-201-%s\n' "$(attempt)"; }
image_name() { printf 'sys-l-201:%s\n' "$(attempt)"; }

validate_target() {
  local engine name expected actual
  engine="$(runtime)"
  name="$(container_name)"
  expected="$(attempt)"
  actual="$("${engine}" inspect --format "{{ index .Config.Labels \"${LABEL_KEY}\" }}" "${name}" 2>/dev/null || true)"
  [[ "${actual}" == "${expected}" ]] || die "el contenedor ${name} no pertenece a este intento"
}

preflight() {
  [[ "${EUID}" -ne 0 ]] || die "no ejecutes este laboratorio como root"
  [[ "$(pwd -P)" != "${SCRIPT_DIR}" ]] || true
  local engine
  engine="$(runtime)"
  "${engine}" info >/dev/null
  printf 'lab=%s runtime=%s attempt=%s directory=%s\n' "${LAB_ID}" "${engine}" "$(attempt)" "${SCRIPT_DIR}"
}

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; usa inspect, reset o destroy"
  fi
  "${engine}" build --tag "${image}" --file "${SCRIPT_DIR}/Containerfile" "${SCRIPT_DIR}"
  "${engine}" run --detach --name "${name}" \
    --label "${LABEL_KEY}=${id}" \
    --pids-limit 64 --memory 192m --cpus 0.50 \
    --tmpfs /lab/data:rw,size=96m,mode=0700 \
    "${image}" >/dev/null
  printf 'started=%s attempt=%s\n' "${name}" "${id}"
}

inspect_state() {
  validate_target
  local engine name
  engine="$(runtime)"; name="$(container_name)"
  "${engine}" exec "${name}" sh -c '
    printf "%s\n" "--- stat ---"
    stat -c "path=%n device=%d inode=%i links=%h size=%s blocks=%b" /lab/data/payload.bin /lab/data/payload-hard.bin /lab/data/payload-current.bin 2>&1 || true
    printf "%s\n" "--- readlink ---"
    readlink /lab/data/payload-current.bin || true
    printf "%s\n" "--- descriptors ---"
    find /proc/1/fd -maxdepth 1 -type l -exec ls -l {} \; 2>/dev/null
    printf "%s\n" "--- df ---"
    df -h /lab/data
    printf "%s\n" "--- du ---"
    du -h /lab/data
  '
}

unlink_payload() {
  validate_target
  "$(runtime)" exec "$(container_name)" rm -- /lab/data/payload.bin
  printf 'unlinked=/lab/data/payload.bin\n'
}

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 ;;
  unlink) unlink_payload ;;
  reset) reset ;;
  destroy) destroy ;;
  *) die "uso: ./lab {preflight|start|inspect|unlink|reset|destroy}" ;;
esac
