#!/usr/bin/env bash

# CANCELLED_DO_NOT_EXECUTE
# Q200 policy is now IP-based read-only network acceptance only.
# Legacy /etc/hosts managed reconcile path is superseded and must not be executed.
if [[ -n "${Q200_FORCE_LEGACY_HOSTS:-}" ]]; then
  :
else
  echo 'CANCELLED_DO_NOT_EXECUTE_POLICY=SUPERSEDED_BY_IP_BASED_Q200'
  echo 'Q200_ACTION=NO_WRITE_DO_NOT_EXECUTE'
  exit 0
fi

set -Eeuo pipefail

BEGIN_MARKER='## BEGIN MANUAL_OPERATOR_MODE SANQUAN_Q200_MANAGED'
END_MARKER='## END MANUAL_OPERATOR_MODE SANQUAN_Q200_MANAGED'
EVIDENCE_DIR='/root/q200-emqx-hosts-evidence'
HOSTS_FILE='/etc/hosts'
BACKUP_FILE=''
FAILED=0

HOSTS_BLOCK=''
while read -r ip host; do
  [[ -z "$ip" || "$ip" == \#* ]] && continue
  [[ -z "$host" ]] && continue
  HOSTS_BLOCK+="${ip} ${host}\n"
done <<'MAPPINGS'
10.2.203.102 sqjcnginx01
10.2.203.103 sqjcnginx02
10.2.203.104 sqjcapp01
10.2.203.105 sqjcapp02
10.2.208.106 sqjcDB01
10.2.208.107 sqjcDB02
10.2.203.108 sqjcmqtt01
10.2.203.109 sqjcmqtt02
10.2.203.110 sqjcmqtt03
10.2.203.112 sqjcredis01
10.2.203.113 sqjcredis02
MAPPINGS

log() { printf '%s %s\n' 'Q200_HOSTS_RECONCILE' "$*"; }

fail() { log "$1"; FAILED=1; }

require_root() {
  [[ $(id -u) -eq 0 ]] || { fail 'REQUIRE_ROOT=FAIL'; exit 1; }
}

validate_mapping_format() {
  local duplicate_ips duplicate_hosts
  duplicate_ips=$(printf '%s' "$HOSTS_BLOCK" | awk '{print $1}' | sort | uniq -d)
  duplicate_hosts=$(printf '%s' "$HOSTS_BLOCK" | awk '{print $2}' | sort | uniq -d)

  if [[ -n "$duplicate_ips" || -n "$duplicate_hosts" ]]; then
    [[ -n "$duplicate_ips" ]] && fail "DUPLICATE_IP=$duplicate_ips"
    [[ -n "$duplicate_hosts" ]] && fail "DUPLICATE_HOSTNAME=$duplicate_hosts"
    return 1
  fi

  while read -r ip host; do
    [[ -z "$ip" || -z "$host" ]] && continue
    if ! [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
      fail "INVALID_IP_FORMAT=$ip"
    fi
    if ! [[ $host =~ ^[A-Za-z0-9._-]+$ ]]; then
      fail "INVALID_HOSTNAME_FORMAT=$host"
    fi
  done <<<"$HOSTS_BLOCK"

  return "$FAILED"
}

backup_hosts() {
  mkdir -p "$EVIDENCE_DIR"
  BACKUP_FILE="$EVIDENCE_DIR/etc-hosts.$(date -u +%Y%m%dT%H%M%SZ).bak"
  cp -p "$HOSTS_FILE" "$BACKUP_FILE"
  chown root:root "$BACKUP_FILE"
  chmod 600 "$BACKUP_FILE"
  log "BACKUP_CREATED=$BACKUP_FILE"
}

restore_hosts() {
  if [[ -n "$BACKUP_FILE" && -f "$BACKUP_FILE" ]]; then
    cp -p "$BACKUP_FILE" "$HOSTS_FILE"
    restore_mode_owner_context "$BACKUP_FILE"
    log "ROLLBACK_RESTORED_FROM=$BACKUP_FILE"
  fi
}

restore_mode_owner_context() {
  local src="$1"
  local mode owner
  mode=$(stat -c %a "$src")
  owner=$(stat -c '%u:%g' "$src")
  chmod "$mode" "$HOSTS_FILE"
  chown "$owner" "$HOSTS_FILE"
  restorecon -Rv "$HOSTS_FILE" >/dev/null 2>&1 || true
}

render_managed_block() {
  {
    printf '%s\n' "$BEGIN_MARKER"
    printf '# Managed by SANQUAN_Q200_MANAGED; do not manually edit this block.\n'
    printf '# Source: authority provided host mapping for Q-200.\n'
    printf '%s\n' "$HOSTS_BLOCK"
    printf '%s\n' "$END_MARKER"
  }
}

build_hosts_content() {
  local cleaned tmpfile="$1"
  # keep non-managed part
  if grep -qF "$BEGIN_MARKER" "$HOSTS_FILE" && grep -qF "$END_MARKER" "$HOSTS_FILE"; then
    awk -v b="$BEGIN_MARKER" -v e="$END_MARKER" '
      $0==b{skip=1; next}
      $0==e{skip=0; next}
      !skip{print}
    ' "$HOSTS_FILE" > "$tmpfile"
  else
    cp -p "$HOSTS_FILE" "$tmpfile"
  fi

  if [[ -s "$tmpfile" && $(tail -n 1 "$tmpfile") != "" ]]; then
    printf '\n' >> "$tmpfile"
  fi
  render_managed_block >> "$tmpfile"

  local b=$(grep -cF "$BEGIN_MARKER" "$tmpfile" || true)
  local e=$(grep -cF "$END_MARKER" "$tmpfile" || true)
  if [[ $b -ne 1 || $e -ne 1 ]]; then
    fail "MANAGED_MARKER_COUNT_INVALID=$b/$e"
    return 1
  fi
  return 0
}

check_resolve() {
  local all_ok=1
  while read -r line; do
    [[ -z "$line" ]] && continue
    local ip host
    ip=$(awk '{print $1}' <<<"$line")
    host=$(awk '{print $2}' <<<"$line")
    [[ -z "$ip" || -z "$host" ]] && continue

    if getent ahostsv4 "$host" | awk -v expected="$ip" '$1==expected {found=1} END {exit !found}'; then
      log "GETENT_HOSTS_PASS=$host $ip"
    else
      fail "GETENT_HOSTS_FAIL=$host"
      all_ok=0
    fi
  done <<<"$HOSTS_BLOCK"
  return $((1-all_ok))
}

main() {
  log 'Q200_HOSTS_RECONCILE_BEGIN'
  log "SCRIPT_SHA256=$(sha256sum "$0" | awk '{print $1}')"
  require_root

  validate_mapping_format || true
  [[ $FAILED -ne 0 ]] && { log 'BLOCKED_PRECHECK_FAIL=1'; exit 1; }

  backup_hosts

  local tmp="$(mktemp /tmp/sanquan-q200-hosts-XXXXXX)"
  local fail_count=0

  if ! build_hosts_content "$tmp"; then
    fail_count=1
  else
    restore_mode_owner_context "$BACKUP_FILE"
    chmod --reference "$BACKUP_FILE" "$tmp"
    chown --reference "$BACKUP_FILE" "$tmp"
    if ! mv "$tmp" "$HOSTS_FILE"; then
      fail_count=1
      fail "ATOMIC_REPLACE_FAILED"
    fi

    if ! check_resolve; then
      fail_count=1
      restore_hosts
    else
      log 'GETENT_ALL_PASS=11'
      log 'Q200_HOSTS_RECONCILE_WRITE_OK=1'
    fi
  fi

  rm -f "$tmp" || true
  log "Q200_HOSTS_RECONCILE_END_RC=$fail_count"
  exit "$fail_count"
}

main "$@"
