#!/bin/bash
# 确保 AppCenter 下各前端的 index.html 带 `Cache-Control: no-cache`。由 appCenterSync.sh 在 manifest 打开
# ensureNoCache 时调用（受 manifest 的灰度门控制）；幂等，已生效时只做几个文件比较就返回。
#
# 病症：设备 Apache 默认没开 mod_headers，index.html 只带 Last-Modified/ETag，浏览器按「文件年龄 × 10%」自行缓存，
# 这段时间里同一个 URL 直接用缓存、不问服务器。aaden-vue-app 打开后台带的 chaos= 是收银程序启动时间，
# 程序不重启 URL 就不变 → appcenter-sync 换了新版也看不到；期间若又发一版，缓存里的旧 index.html
# 去请求已被清掉的旧 chunk → 白屏。js/css 文件名带内容 hash，不受影响，所以只管 index.html。
# no-cache = 每次用之前先向服务器确认，不是不缓存。（mod_deflate 给 ETag 加了 -gzip，条件请求对不上，
# 实际每次回 200 约 3KB 而不是 304，可忽略。）只对之后的新响应生效，已缓存的旧响应要等它自己过期。
#
# 风险控制（配置写坏时 reload 会被 configtest 拦住、继续跑旧配置，但下次重启 Apache 就起不来、收银全停）：
#   - 动手前先 configtest：本来就过不了的设备一律不碰
#   - 配置包在 <IfModule> 里；写完立刻 configtest，不过就原样撤回（删配置、关掉本次才开的模块）
#   - 只 graceful reload，不 restart：正在处理的请求（打印、TSE 签名）不被打断
# 末行输出：NOCACHE_OK（已生效）| NOCACHE_APPLIED | NOCACHE_SKIP_<原因> | NOCACHE_REVERTED | NOCACHE_FAILED
# 退出码：只有 NOCACHE_FAILED（撤回后配置仍坏 / reload 失败）为 1
# 撤销：a2disconf aaden-appcenter-cache && systemctl reload apache2
set -u
# root 的 cron（auto-upgrade）PATH 只有 /usr/local/bin:/usr/bin:/bin，apache2ctl / a2enmod 在 /usr/sbin，
# 不补的话下面的 command -v 永远找不到 → 每天报 NOCACHE_SKIP_NO_APACHE、no-cache 永远装不上
export PATH="$PATH:/usr/local/sbin:/usr/sbin:/sbin"
NAME=aaden-appcenter-cache
CONF=/etc/apache2/conf-available/$NAME.conf
PW='Innerken322.'
sudoS(){ echo "$PW" | sudo -S bash -c "$*"; }
configtest(){ sudoS "apache2ctl configtest" >/dev/null 2>&1; }

if ! command -v apache2ctl >/dev/null || ! command -v a2enmod >/dev/null; then
  echo "  没有 apache2ctl/a2enmod（不是 apt 装的 Apache？），不碰"; echo "NOCACHE_SKIP_NO_APACHE"; exit 0
fi

TMP=$(mktemp)
trap 'rm -f "$TMP" "$TMP.old"' EXIT
cat > "$TMP" <<'EOF'
# 由 aaden-cli AadenDeploy/ensureAppCenterNoCache.sh 维护，手改会被覆盖。
# AppCenter 前端的入口页每次先向服务器确认，避免更新后还在用缓存里的旧 index.html。
# 只匹配 /var/www/html/AppCenter 下的 index.html；PHP 接口、js/css、根目录 /App/ /Admin/ 不受影响。
<IfModule mod_headers.c>
  <Directory /var/www/html/AppCenter>
    <FilesMatch "^index\.html$">
      Header set Cache-Control "no-cache"
    </FilesMatch>
  </Directory>
</IfModule>
EOF

MOD_WAS_ON=0; [ -e /etc/apache2/mods-enabled/headers.load ] && MOD_WAS_ON=1
CONF_WAS_ON=0; [ -e "/etc/apache2/conf-enabled/$NAME.conf" ] && CONF_WAS_ON=1
if [ "$MOD_WAS_ON" = 1 ] && [ "$CONF_WAS_ON" = 1 ] && cmp -s "$TMP" "$CONF"; then
  echo "NOCACHE_OK"; exit 0
fi
if ! configtest; then
  echo "  Apache 配置本来就过不了 configtest，不碰（这台设备需要人工处理）"; echo "NOCACHE_SKIP_CONFIG_BROKEN"; exit 0
fi
HAD_CONF=0; [ -f "$CONF" ] && { HAD_CONF=1; cp "$CONF" "$TMP.old"; }

# 撤回到动手前的状态：只关本次才开的模块/配置，原来就有的不碰
revert(){
  [ "$CONF_WAS_ON" = 0 ] && sudoS "a2disconf -q $NAME" >/dev/null 2>&1
  if [ "$HAD_CONF" = 1 ]; then sudoS "cp '$TMP.old' '$CONF'"; else sudoS "rm -f '$CONF'"; fi
  [ "$MOD_WAS_ON" = 0 ] && sudoS "a2dismod -q headers" >/dev/null 2>&1
  if configtest; then echo "  已撤回，Apache 配置恢复正常"; return 0; fi
  echo "  !!! 撤回后 configtest 仍失败，需要人工处理（重启前务必修好）"; return 1
}

sudoS "cp '$TMP' '$CONF' && chmod 644 '$CONF'"
[ "$MOD_WAS_ON" = 1 ] || sudoS "a2enmod -q headers" >/dev/null
[ "$CONF_WAS_ON" = 1 ] || sudoS "a2enconf -q $NAME" >/dev/null

if ! configtest; then
  echo "  写入后 configtest 失败（未 reload，线上仍是旧配置），撤回"
  if revert; then echo "NOCACHE_REVERTED"; exit 0; fi
  echo "NOCACHE_FAILED"; exit 1
fi
if ! sudoS "systemctl reload apache2 || apache2ctl graceful"; then
  echo "  reload 失败，撤回"
  revert; echo "NOCACHE_FAILED"; exit 1
fi

# graceful 后新配置由新起的子进程接手，稍等再验
sleep 2
if [ -f /var/www/html/AppCenter/Admin/index.html ]; then
  H=$(curl -sI --max-time 10 http://localhost/AppCenter/Admin/ | tr -d '\r' | grep -i '^cache-control:')
  echo "  验证 /AppCenter/Admin/ -> ${H:-（没有 Cache-Control 头！）}"
fi
echo "NOCACHE_APPLIED"
