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

# Usage:
#   scripts/send-wazuh-proposal-appendix-c-events.sh [selector] [count] [delay_seconds] [--forever]
#
# selector:
#   all | c1 | c2 | c3 | <usecase_id>
#   example usecase_id: C1-01, C2-03, C3-04

SELECTOR="${1:-all}"
COUNT="${2:-1}"
DELAY="${3:-0.3}"
EVENT_DELAY="${EVENT_DELAY:-0.05}"
DRY_RUN="${DRY_RUN:-0}"
FOREVER="false"

for arg in "${@:4}"; do
  case "${arg}" in
    --forever)
      FOREVER="true"
      ;;
    *)
      echo "error: unexpected argument '${arg}'"
      echo "usage: scripts/send-wazuh-proposal-appendix-c-events.sh [selector] [count] [delay_seconds] [--forever]"
      exit 1
      ;;
  esac
done

WAZUH_SYSLOG_HOST="${WAZUH_SYSLOG_HOST:-127.0.0.1}"
WAZUH_SYSLOG_PORT="${WAZUH_SYSLOG_PORT:-514}"
VPN_HOST="${VPN_HOST:-fgt-vpn-01}"
WIN_HOST="${WIN_HOST:-win-ad-01}"
SIM_USER="${SIM_USER:-alice.admin}"
SIM_SERVICE_USER="${SIM_SERVICE_USER:-svc_backup}"
SIM_SRC_IP="${SIM_SRC_IP:-203.0.113.44}"

if ! [[ "${COUNT}" =~ ^[0-9]+$ ]] || [[ "${COUNT}" -lt 1 ]]; then
  echo "error: count must be a positive integer"
  exit 1
fi

if ! [[ "${DELAY}" =~ ^[0-9]+([.][0-9]+)?$ ]]; then
  echo "error: delay must be numeric"
  exit 1
fi

emit_syslog() {
  local msg="$1"
  local sent="false"

  if [[ "${DRY_RUN}" == "1" ]]; then
    echo "[DRY_RUN $(date -u +'%Y-%m-%dT%H:%M:%SZ')] ${msg}"
    return 0
  fi

  if command -v nc >/dev/null 2>&1; then
    if printf "%s\n" "${msg}" | nc -u -w1 "${WAZUH_SYSLOG_HOST}" "${WAZUH_SYSLOG_PORT}"; then
      sent="true"
    fi
  fi

  if [[ "${sent}" != "true" ]]; then
    if printf "%s\n" "${msg}" >"/dev/udp/${WAZUH_SYSLOG_HOST}/${WAZUH_SYSLOG_PORT}" 2>/dev/null; then
      sent="true"
    fi
  fi

  if [[ "${sent}" != "true" ]]; then
    echo "error: failed to send syslog event to ${WAZUH_SYSLOG_HOST}:${WAZUH_SYSLOG_PORT}/udp"
    return 1
  fi

  echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] sent: ${msg}"
}

selector_matches() {
  local id="$1"
  local section="$2"
  local sel
  sel="$(echo "${SELECTOR}" | tr '[:upper:]' '[:lower:]')"
  local idl
  idl="$(echo "${id}" | tr '[:upper:]' '[:lower:]')"
  local sec
  sec="$(echo "${section}" | tr '[:upper:]' '[:lower:]')"
  [[ "${sel}" == "all" || "${sel}" == "${sec}" || "${sel}" == "${idl}" ]]
}

emit_c_usecase() {
  local id="$1"
  local section="$2"
  local severity="$3"
  local host="$4"
  local usecase="$5"
  local body="$6"

  selector_matches "${id}" "${section}" || return 0
  emit_syslog "<182>$(date '+%b %d %H:%M:%S') ${host} soc_mvp_test=true source=windows section=${section} usecase_id=${id} severity=${severity} usecase=\"${usecase}\" ${body}"
  sleep "${EVENT_DELAY}"
}

emit_c1() {
  # Two successful logins by same user with impossible travel profile
  emit_c_usecase "C1-01" "C1" "high" "${VPN_HOST}" \
    "Impossible Travel Detection" \
    "event_type=vpn_login_success event_id=4624 success=true user=\"${SIM_USER}\" src_ip=203.150.10.10 country=TH src_lat=13.7563 src_lon=100.5018 dst_host=vpn-gw-01"

  emit_c_usecase "C1-01" "C1" "high" "${VPN_HOST}" \
    "Impossible Travel Detection" \
    "event_type=vpn_login_success event_id=4624 success=true user=\"${SIM_USER}\" src_ip=8.8.8.8 country=US src_lat=37.3861 src_lon=-122.0839 dst_host=vpn-gw-01"
}

emit_c2() {
  emit_c_usecase "C2-01" "C2" "high" "${WIN_HOST}" \
    "Privileged Account Usage Outside Business Hours" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"administrator\" is_admin=true src_ip=${SIM_SRC_IP} logon_type=10 dst_host=dc-01"

  emit_c_usecase "C2-02" "C2" "medium" "${WIN_HOST}" \
    "Dormant Account Activation" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"legacy.user\" src_ip=198.51.100.55 dst_host=dc-01"

  emit_c_usecase "C2-03" "C2" "high" "${WIN_HOST}" \
    "Service Account Interactive Logon" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"${SIM_SERVICE_USER}\" account_type=service is_service=true logon_type=10 src_ip=198.51.100.66 dst_host=filesrv-01"

  emit_c_usecase "C2-04" "C2" "high" "${WIN_HOST}" \
    "Rapid Privilege Escalation then Sensitive Access" \
    "event_type=windows_privilege_group_add event_id=4732 user=\"${SIM_USER}\" action=group_add is_admin=true src_ip=10.10.1.20 dst_host=dc-01"

  emit_c_usecase "C2-04" "C2" "high" "${WIN_HOST}" \
    "Rapid Privilege Escalation then Sensitive Access" \
    "event_type=windows_file_share_access event_id=5145 user=\"${SIM_USER}\" action=share_access src_ip=10.10.1.20 dst_host=filesrv-02 dst_port=445"
}

emit_c3() {
  emit_c_usecase "C3-01" "C3" "high" "${WIN_HOST}" \
    "Multiple Authentication Success Across Hosts" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"ops.user\" src_ip=10.20.0.15 dst_host=app-01 dst_port=3389"
  emit_c_usecase "C3-01" "C3" "high" "${WIN_HOST}" \
    "Multiple Authentication Success Across Hosts" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"ops.user\" src_ip=10.20.0.15 dst_host=app-02 dst_port=3389"
  emit_c_usecase "C3-01" "C3" "high" "${WIN_HOST}" \
    "Multiple Authentication Success Across Hosts" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"ops.user\" src_ip=10.20.0.15 dst_host=db-01 dst_port=3389"
  emit_c_usecase "C3-01" "C3" "high" "${WIN_HOST}" \
    "Multiple Authentication Success Across Hosts" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"ops.user\" src_ip=10.20.0.15 dst_host=db-02 dst_port=3389"
  emit_c_usecase "C3-01" "C3" "high" "${WIN_HOST}" \
    "Multiple Authentication Success Across Hosts" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"ops.user\" src_ip=10.20.0.15 dst_host=fs-01 dst_port=3389"

  emit_c_usecase "C3-02" "C3" "high" "${WIN_HOST}" \
    "SMB/RDP Lateral Burst Pattern" \
    "event_type=windows_lateral_movement event_id=4624 success=true user=\"ops.user\" src_ip=10.20.0.15 dst_host=rdp-01 dst_port=3389"
  emit_c_usecase "C3-02" "C3" "high" "${WIN_HOST}" \
    "SMB/RDP Lateral Burst Pattern" \
    "event_type=windows_lateral_movement event_id=4624 success=true user=\"ops.user\" src_ip=10.20.0.15 dst_host=smb-01 dst_port=445"
  emit_c_usecase "C3-02" "C3" "high" "${WIN_HOST}" \
    "SMB/RDP Lateral Burst Pattern" \
    "event_type=windows_lateral_movement event_id=4624 success=true user=\"ops.user\" src_ip=10.20.0.15 dst_host=smb-02 dst_port=445"
  emit_c_usecase "C3-02" "C3" "high" "${WIN_HOST}" \
    "SMB/RDP Lateral Burst Pattern" \
    "event_type=windows_lateral_movement event_id=4624 success=true user=\"ops.user\" src_ip=10.20.0.15 dst_host=rdp-02 dst_port=3389"

  emit_c_usecase "C3-03" "C3" "critical" "${WIN_HOST}" \
    "Admin Accessing Many Servers Rapidly" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"administrator\" is_admin=true src_ip=10.20.0.22 dst_host=adm-01 dst_port=3389"
  emit_c_usecase "C3-03" "C3" "critical" "${WIN_HOST}" \
    "Admin Accessing Many Servers Rapidly" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"administrator\" is_admin=true src_ip=10.20.0.22 dst_host=adm-02 dst_port=3389"
  emit_c_usecase "C3-03" "C3" "critical" "${WIN_HOST}" \
    "Admin Accessing Many Servers Rapidly" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"administrator\" is_admin=true src_ip=10.20.0.22 dst_host=adm-03 dst_port=3389"
  emit_c_usecase "C3-03" "C3" "critical" "${WIN_HOST}" \
    "Admin Accessing Many Servers Rapidly" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"administrator\" is_admin=true src_ip=10.20.0.22 dst_host=adm-04 dst_port=3389"
  emit_c_usecase "C3-03" "C3" "critical" "${WIN_HOST}" \
    "Admin Accessing Many Servers Rapidly" \
    "event_type=windows_auth_success event_id=4624 success=true user=\"administrator\" is_admin=true src_ip=10.20.0.22 dst_host=adm-05 dst_port=3389"

  # C3-04 scanning behavior: many destination ports from same source
  for port in 80 88 135 139 389 443 445 464 636 1025 1433 1521 2049 2375 3306 3389 5432 5985 8080 8443; do
    emit_c_usecase "C3-04" "C3" "medium" "${WIN_HOST}" \
      "Internal Scanning Enumeration Behavior" \
      "event_type=internal_scan src_ip=10.30.0.40 dst_host=10.30.10.$((RANDOM % 10 + 1)) dst_port=${port} action=connect_attempt"
  done
}

emit_selected_set() {
  local sel
  sel="$(echo "${SELECTOR}" | tr '[:upper:]' '[:lower:]')"
  case "${sel}" in
    all)
      emit_c1
      emit_c2
      emit_c3
      ;;
    c1|c1-*)
      emit_c1
      ;;
    c2|c2-*)
      emit_c2
      ;;
    c3|c3-*)
      emit_c3
      ;;
    *)
      emit_c1
      emit_c2
      emit_c3
      ;;
  esac
}

echo "starting proposal Appendix C log simulator"
echo "selector=${SELECTOR} count=${COUNT} delay=${DELAY}s event_delay=${EVENT_DELAY}s dry_run=${DRY_RUN}"
echo "target=${WAZUH_SYSLOG_HOST}:${WAZUH_SYSLOG_PORT}/udp"

if [[ "${FOREVER}" == "true" ]]; then
  echo "running forever with interval ${DELAY}s (Ctrl+C to stop)"
  trap 'echo; echo "stopped"; exit 0' INT TERM
  while true; do
    emit_selected_set
    sleep "${DELAY}"
  done
else
  for ((i=1; i<=COUNT; i++)); do
    emit_selected_set
    if [[ "${i}" -lt "${COUNT}" ]]; then
      sleep "${DELAY}"
    fi
  done
  echo "done"
fi
