#!/usr/bin/env bash

set -Eeuo pipefail
umask 077

readonly EXPECTED_HOSTNAME='sqjcmqtt01'
readonly EXPECTED_IP='10.2.203.108'
readonly NODE_ENV='/etc/zhct/node.env'
readonly AUDIT_LOG='/root/q141-node-env-readonly-diagnose.log'

exec > >(tee "${AUDIT_LOG}") 2>&1

q141_diag_finish() {
  q141_diag_rc=$?
  trap - EXIT
  printf '%s\n' 'Q141_NODE_ENV_READONLY_DIAG_END'
  printf 'Q141_NODE_ENV_READONLY_DIAG_RC=%s\n' "${q141_diag_rc}"
  exit "${q141_diag_rc}"
}
trap q141_diag_finish EXIT

printf '%s\n' 'Q141_NODE_ENV_READONLY_DIAG_BEGIN'

hostname -s | grep -Fx "${EXPECTED_HOSTNAME}"
ip -br -4 addr show ens192 | grep -F "${EXPECTED_IP}/24"

printf '%s\n' '=== NODE ENV METADATA ==='
stat -c 'NODE_ENV_OWNER=%U:%G NODE_ENV_MODE=%a NODE_ENV_SIZE=%s' "${NODE_ENV}"
sha256sum "${NODE_ENV}"

printf '%s\n' '=== NODE ENV STRUCTURE ==='
awk '
  {
    line = $0
    total += 1
    if (line ~ /\r$/) {
      crlf += 1
      sub(/\r$/, "", line)
    }
    if (line ~ /^[ \t]*$/) {
      blank += 1
    }
    if (line ~ /[ \t]+$/) {
      trailing += 1
    }
  }
  END {
    printf "NODE_ENV_TOTAL_LINES=%d\n", total + 0
    printf "NODE_ENV_CRLF_LINES=%d\n", crlf + 0
    printf "NODE_ENV_BLANK_LINES=%d\n", blank + 0
    printf "NODE_ENV_TRAILING_WHITESPACE_LINES=%d\n", trailing + 0
  }
' "${NODE_ENV}"

printf '%s\n' '=== EXPECTED LINE MATCHES ==='
q141_diag_rc=0
while IFS='|' read -r q141_key q141_expected; do
  q141_present_count=$(
    awk -v key="${q141_key}" '
      index($0, key "=") == 1 { count += 1 }
      END { print count + 0 }
    ' "${NODE_ENV}"
  )
  q141_match_count=$(
    awk -v key="${q141_key}" -v expected="${q141_expected}" '
      $0 == key "=" expected { count += 1 }
      END { print count + 0 }
    ' "${NODE_ENV}"
  )
  printf 'ALLOWLIST_KEY=%s PRESENT_COUNT=%s EXACT_MATCH_COUNT=%s\n' \
    "${q141_key}" "${q141_present_count}" "${q141_match_count}"
  if [[ "${q141_present_count}" -eq 1 && "${q141_match_count}" -eq 1 ]]; then
    printf 'ALLOWLIST_KEY_STATUS=%s:PASS\n' "${q141_key}"
  else
    printf 'ALLOWLIST_KEY_STATUS=%s:FAIL\n' "${q141_key}"
    q141_diag_rc=1
  fi
done <<'Q141_ALLOWLIST'
ROLE|emqx
NODE_KEY|emqx01
NODE_IP|10.2.203.108
NODE_NAME|sqjcmqtt01
Q141_ALLOWLIST

printf '%s\n' '=== UNKNOWN KEY NAMES ONLY ==='
awk '
  BEGIN {
    allow["ROLE"] = 1
    allow["NODE_KEY"] = 1
    allow["NODE_IP"] = 1
    allow["NODE_NAME"] = 1
  }
  {
    line = $0
    sub(/\r$/, "", line)
    separator = index(line, "=")
    if (separator == 0) {
      invalid_lines += 1
      next
    }
    key = substr(line, 1, separator - 1)
    if (key in allow) {
      next
    }
    if (key ~ /^[A-Z][A-Z0-9_]{0,63}$/) {
      unknown[key] = 1
    } else {
      invalid_key_names += 1
    }
  }
  END {
    count = 0
    for (key in unknown) {
      count += 1
      printf "UNKNOWN_KEY_NAME=%s\n", key
    }
    printf "UNKNOWN_KEY_NAME_COUNT=%d\n", count
    printf "INVALID_OR_UNFILTERED_LINE_COUNT=%d\n",
      invalid_lines + invalid_key_names
  }
' "${NODE_ENV}" | LC_ALL=C sort

if cmp -s \
  <(printf '%s\n' \
    'ROLE=emqx' \
    'NODE_KEY=emqx01' \
    'NODE_IP=10.2.203.108' \
    'NODE_NAME=sqjcmqtt01') \
  "${NODE_ENV}"; then
  printf '%s\n' 'NODE_ENV_EXACT_CONTENT=PASS'
else
  printf '%s\n' 'NODE_ENV_EXACT_CONTENT=FAIL'
  q141_diag_rc=1
fi

if [[ "${q141_diag_rc}" -eq 0 ]]; then
  printf '%s\n' 'Q141_NODE_ENV_READONLY_DIAG_PASS'
else
  printf '%s\n' 'Q141_NODE_ENV_READONLY_DIAG_FAIL'
fi

exit "${q141_diag_rc}"
