#!/usr/bin/env bash

set -uo pipefail

EXPECTED_HOST=sqjcapp02
EXPECTED_IP=10.2.203.105
bad=0

mark_bad() {
    printf 'FAIL: %s\n' "$1"
    bad=1
}

echo Q110_APP02_READONLY_GATE_BEGIN
date '+%Y-%m-%dT%H:%M:%S%z'
echo "EXPECTED_HOST=$EXPECTED_HOST EXPECTED_IP=$EXPECTED_IP"

actual_host=$(hostname -s 2>&1 || true)
ipv4=$(ip -o -4 addr show scope global 2>&1 || true)
echo "ACTUAL_HOST=$actual_host"
printf '%s\n' "$ipv4"
[[ "$actual_host" == "$EXPECTED_HOST" ]] || mark_bad "hostname mismatch"
grep -Eq "(^|[[:space:]])${EXPECTED_IP//./\\.}/" <<<"$ipv4" || mark_bad "expected IPv4 missing"

echo '=== IDENTITY_INVENTORY ==='
stat -c 'path=%n type=%F mode=%a owner=%U:%G size=%s mtime=%y' /etc/machine-id 2>&1 || mark_bad "/etc/machine-id missing"
if [[ -e /var/lib/dbus/machine-id || -L /var/lib/dbus/machine-id ]]; then
    stat -c 'path=%n type=%F mode=%a owner=%U:%G size=%s mtime=%y' /var/lib/dbus/machine-id 2>&1 || true
else
    echo 'ABSENT path=/var/lib/dbus/machine-id'
fi
find /etc/ssh -maxdepth 1 -type f -name 'ssh_host_*_key*' \
    -printf 'SSH_HOST_FILE path=%p mode=%m owner=%u:%g size=%s mtime=%TY-%Tm-%TdT%TH:%TM:%TS%Tz\n' \
    2>&1 | sort

echo '=== FRAMEWORK_SHA256 ==='
while read -r expected path; do
    if [[ ! -f "$path" || -L "$path" ]]; then
        mark_bad "framework file missing or unsafe: $path"
        continue
    fi
    actual=$(sha256sum "$path" | awk '{print $1}')
    echo "$actual  $path"
    [[ "$actual" == "$expected" ]] || mark_bad "framework SHA mismatch: $path"
done <<'EOF'
ca5fa0a113739bcbe3ff51b2815bb50723cd8b1cf33dfb6d3f3f172caf2dabc6 /opt/zhct-deploy/common/scripts/post-clone.sh
e637ca657a897c6d0b689bbd6347f04516baf5c9f32350cd1e8a2071c211a0a5 /opt/zhct-deploy/common/scripts/activate-role.sh
e3eae16aa5c87f43b56495fc71de378a947578cabe18b507e8fed01ac1f32025 /opt/zhct-deploy/common/bin/role-action.sh
03c6b13a0def5bf3954e069581b6f9fbe0f81f24285ba2319b6279c0406d70aa /opt/zhct-deploy/roles/app/hooks.sh
83e6abb26b4af6d8a8dc74082acac73009d0d60446bd641f65b8b4e9c21e6afc /opt/zhct-deploy/roles/app/manifests/nodes.tsv
d43e179c108f6db551b452256f867d6d4f6fc9e031c1d4def2f343966af8d684 /opt/zhct-deploy/roles/app/manifests/systemd-units.tsv
EOF

echo '=== NODE_ENV ==='
if [[ -e /etc/zhct/node.env || -L /etc/zhct/node.env ]]; then
    awk -F= '$1 ~ /^(ROLE|NODE_KEY|NODE_IP|NODE_NAME|APPLIED_AT)$/ {print}' /etc/zhct/node.env 2>&1 || true
    mark_bad "node.env already exists before authorized Q-110 post-clone"
else
    echo 'ABSENT path=/etc/zhct/node.env'
fi

echo '=== QUIESCENT_UNIT_STATE ==='
for unit in nginx.service php-fpm73.service php-fpm74.service supervisor.service crond.service; do
    enabled=$(systemctl is-enabled "$unit" 2>/dev/null || true)
    active=$(systemctl is-active "$unit" 2>/dev/null || true)
    sub=$(systemctl show "$unit" -p SubState --value 2>/dev/null || true)
    echo "$unit enabled=$enabled active=$active sub=$sub"
    [[ "$enabled" == disabled && "$active" == inactive ]] || mark_bad "unit is not disabled/inactive: $unit"
done

echo '=== TARGET_LISTENERS ==='
listeners=$(ss -H -lntup 2>&1 | awk '$5 ~ /:(8081|18081)$/')
if [[ -n "$listeners" ]]; then
    printf '%s\n' "$listeners"
    mark_bad "target listener exists"
else
    echo TARGET_LISTENERS_ZERO
fi

echo '=== TARGET_PROCESSES ==='
process_bad=0
for process in nginx php-fpm supervisord crond mysqld mysqld_safe redis-server mosquitto; do
    if output=$(pgrep -a -x "$process" 2>/dev/null); then
        printf '%s\n' "$output"
        process_bad=1
    fi
done
if ((process_bad)); then
    mark_bad "target process exists"
else
    echo TARGET_PROCESSES_ZERO
fi

echo '=== APPLICATION_ROOTS ==='
for path in \
    /workspace/wwwroot/zhct_sanquan \
    /workspace/wwwroot/aizhct_sanquan \
    /workspace/wwwroot/ai_store_sanquan
do
    if [[ -e "$path" || -L "$path" ]]; then
        stat -c 'APP_PATH path=%n type=%F mode=%a owner=%U:%G size=%s mtime=%y' "$path" 2>&1 || true
        mark_bad "formal application root already exists: $path"
    else
        echo "ABSENT path=$path"
    fi
done

echo "Q110_APP02_READONLY_GATE_BAD=$bad"
if ((bad == 0)); then
    echo Q110_APP02_READONLY_GATE_RESULT=PASS
else
    echo Q110_APP02_READONLY_GATE_RESULT=FAIL
fi
echo Q110_APP02_READONLY_GATE_END
exit "$bad"
