from pathlib import Path
p = Path('diagnose/check-disk-bark.sh')
s = p.read_text()
# Add mode parse and secondary envs near top.
s = s.replace('''TS="$(date +%Y%m%d_%H%M%S)"\nTARGET_HOST="${1:-localhost}"\nTHRESHOLD="${2:-${DISK_ALERT_THRESHOLD:-98}}"\n''', '''TS="$(date +%Y%m%d_%H%M%S)"\nMODE="${MONCHK_MODE:-threshold}"\nif [ "${1:-}" = "--heartbeat" ]; then\n  MODE="heartbeat"\n  shift\nfi\nTARGET_HOST="${1:-localhost}"\nTHRESHOLD="${2:-${DISK_ALERT_THRESHOLD:-98}}"\n''')
s = s.replace('''BARK_SERVER_VALUE="${BARK_SERVER:-https://api.day.app}"\nBARK_KEY_VALUE="${BARK_KEY:-}"\nBARK_PROXY_VALUE="${BARK_PROXY:-}"\n''', '''BARK_SERVER_VALUE="${BARK_SERVER:-https://api.day.app}"\nBARK_KEY_VALUE="${BARK_KEY:-}"\nBARK_PROXY_VALUE="${BARK_PROXY:-}"\nBARK_SECONDARY_SERVER_VALUE="${BARK_SECONDARY_SERVER:-$BARK_SERVER_VALUE}"\nBARK_SECONDARY_KEY_VALUE="${BARK_SECONDARY_KEY:-}"\nBARK_SECONDARY_PROXY_VALUE="${BARK_SECONDARY_PROXY:-}"\n''')
old = s[s.index('send_bark_alert() {'):s.index('\ncleanup() {')]
new = r'''send_bark_via_http() {
  local channel="$1"
  local server="$2"
  local key="$3"
  local proxy="$4"
  local title="$5"
  local body="$6"
  local group="$7"
  local api_url
  local encoded_title
  local encoded_body
  local encoded_group
  local curl_args=()
  local rc=0

  log "func=send_bark_via_http enter channel=$channel server=$server group=$group"
  [ -n "$key" ] || return 9

  if [ -n "$proxy" ]; then
    curl_args+=(--proxy "$proxy")
    log "func=send_bark_via_http proxy_configured=yes proxy_redacted=yes channel=$channel"
  else
    log "func=send_bark_via_http skip reason=no_proxy channel=$channel"
  fi

  encoded_title="$(url_encode "$title")"
  encoded_body="$(url_encode "$body")"
  encoded_group="$(url_encode "$group")"
  api_url="$server/$key/$encoded_title/$encoded_body?group=$encoded_group"

  set +e
  curl -fsS --connect-timeout 10 --max-time 30 "$api_url" >/dev/null
  rc=$?
  set -e
  if [ "$rc" -eq 0 ]; then
    log "func=send_bark_via_http success mode=direct channel=$channel server=$server"
    return 0
  fi

  if [ "${#curl_args[@]}" -eq 0 ]; then
    log "func=send_bark_via_http failed mode=direct channel=$channel rc=$rc no_proxy_fallback"
    return "$rc"
  fi

  log "func=send_bark_via_http direct_failed rc=$rc fallback=proxy channel=$channel"
  set +e
  curl -fsS --connect-timeout 10 --max-time 30 "${curl_args[@]}" "$api_url" >/dev/null
  rc=$?
  set -e
  if [ "$rc" -eq 0 ]; then
    log "func=send_bark_via_http success mode=proxy channel=$channel server=$server"
    return 0
  fi
  log "func=send_bark_via_http failed mode=proxy channel=$channel rc=$rc"
  return "$rc"
}

send_bark_alert() {
  local title="$1"
  local body="$2"
  local rc=0
  local secondary_rc=0

  log "func=send_bark_alert enter title=$title"
  if command -v bark >/dev/null 2>&1; then
    log "func=send_bark_alert mode=bark_cli"
    if [ -n "$BARK_KEY_VALUE" ]; then
      bark "$title" "$body" -g "$BARK_GROUP" -k "$BARK_KEY_VALUE" >/dev/null
    else
      bark "$title" "$body" -g "$BARK_GROUP" >/dev/null
    fi
    log "func=send_bark_alert success mode=bark_cli group=$BARK_GROUP host=$HOST_LABEL"
    return 0
  fi

  log "func=send_bark_alert mode=curl_api"
  require_command curl

  set +e
  send_bark_via_http primary "$BARK_SERVER_VALUE" "$BARK_KEY_VALUE" "$BARK_PROXY_VALUE" "$title" "$body" "$BARK_GROUP"
  rc=$?
  set -e
  if [ "$rc" -eq 0 ]; then
    if [ -n "$BARK_SECONDARY_KEY_VALUE" ]; then
      set +e
      send_bark_via_http secondary "$BARK_SECONDARY_SERVER_VALUE" "$BARK_SECONDARY_KEY_VALUE" "$BARK_SECONDARY_PROXY_VALUE" "$title" "$body" "${BARK_SECONDARY_GROUP:-$BARK_GROUP}"
      secondary_rc=$?
      set -e
      if [ "$secondary_rc" -ne 0 ]; then
        log "func=send_bark_alert secondary_failed primary_ok=yes rc=$secondary_rc"
      fi
    fi
    log "func=send_bark_alert success primary_ok=yes group=$BARK_GROUP host=$HOST_LABEL"
    return 0
  fi

  if [ -n "$BARK_SECONDARY_KEY_VALUE" ]; then
    set +e
    send_bark_via_http secondary "$BARK_SECONDARY_SERVER_VALUE" "$BARK_SECONDARY_KEY_VALUE" "$BARK_SECONDARY_PROXY_VALUE" "$title" "$body" "${BARK_SECONDARY_GROUP:-$BARK_GROUP}"
    secondary_rc=$?
    set -e
    if [ "$secondary_rc" -eq 0 ]; then
      log "func=send_bark_alert success primary_failed_rc=$rc secondary_ok=yes host=$HOST_LABEL"
      return 0
    fi
    fail "Bark 主备通道均发送失败: primary_rc=$rc secondary_rc=$secondary_rc"
  fi

  fail "Bark 主通道发送失败且未配置备用通道: primary_rc=$rc"
}
'''.replace('\\"','"')
s = s.replace(old, new)
# Replace main log line to include mode and add heartbeat branch.
s = s.replace('''  log "func=main enter target_host=$TARGET_HOST threshold=$THRESHOLD log_file=$LOG_FILE"\n''', '''  log "func=main enter mode=$MODE target_host=$TARGET_HOST threshold=$THRESHOLD log_file=$LOG_FILE"\n''')
s = s.replace('''  disk_lines="$(collect_disk_usage)"\n  analyze_disk_usage "$disk_lines"\n\n  if [ "$ALERT_COUNT" -gt 0 ]; then\n''', '''  disk_lines="$(collect_disk_usage)"\n  analyze_disk_usage "$disk_lines"\n\n  if [ "$MODE" = "heartbeat" ]; then\n    bark_title="[磁盘心跳] $HOST_LABEL 磁盘监控正常"\n    bark_body="host=$HOST_LABEL\\nthreshold=${THRESHOLD}%\\ntime=$(date '+%Y-%m-%d %H:%M:%S')\\nstatus=heartbeat_ok\\n\\n$disk_lines"\n    send_bark_alert "$bark_title" "$bark_body"\n    printf 'HEARTBEAT\\nhost=%s\\nthreshold=%s\\nstatus=sent\\n' "$HOST_LABEL" "$THRESHOLD"\n    log "func=main heartbeat_sent host=$HOST_LABEL threshold=$THRESHOLD"\n    return 0\n  fi\n\n  if [ "$ALERT_COUNT" -gt 0 ]; then\n''')
p.write_text(s)

# Patch bin/run
p = Path('bin/run')
s = p.read_text()
s = s.replace('''  diagnose-disk-bark [host] [threshold] 磁盘 >= threshold 时发 Bark 告警\n''', '''  diagnose-disk-bark [host] [threshold] 磁盘 >= threshold 时发 Bark 告警\n  diagnose-disk-bark-heartbeat [host] [threshold] 发送磁盘 Bark 心跳\n''')
s = s.replace('''  diagnose-disk-bark)\n    exec "$ROOT_DIR/diagnose/check-disk-bark.sh" "$@"\n    ;;\n''', '''  diagnose-disk-bark)\n    exec "$ROOT_DIR/diagnose/check-disk-bark.sh" "$@"\n    ;;\n  diagnose-disk-bark-heartbeat)\n    exec "$ROOT_DIR/diagnose/check-disk-bark.sh" --heartbeat "$@"\n    ;;\n''')
p.write_text(s)

# Patch install script env and units
p = Path('deploy/systemd/install-disk-alert-systemd.sh')
s = p.read_text()
s = s.replace('''SERVICE_NAME=monchk-disk-alert.service\nTIMER_NAME=monchk-disk-alert.timer\n''', '''SERVICE_NAME=monchk-disk-alert.service\nTIMER_NAME=monchk-disk-alert.timer\nHEARTBEAT_SERVICE_NAME=monchk-disk-alert-heartbeat.service\nHEARTBEAT_TIMER_NAME=monchk-disk-alert-heartbeat.timer\n''')
s = s.replace('''BARK_PROXY=\nLOG_DIR=/home/admin/ops-repos/monitor-server-data-check-skills/runtime/logs\nBARK_GROUP=monchk-disk-alert\n''', '''BARK_PROXY=\nBARK_SECONDARY_SERVER=https://api.day.app\nBARK_SECONDARY_KEY=\nBARK_SECONDARY_PROXY=\nBARK_SECONDARY_GROUP=monchk-disk-alert-secondary\nLOG_DIR=/home/admin/ops-repos/monitor-server-data-check-skills/runtime/logs\nBARK_GROUP=monchk-disk-alert\n''')
s = s.replace('''  install_unit "$ROOT_DIR/deploy/systemd/monchk-disk-alert.service" "$SYSTEMD_DIR/$SERVICE_NAME"\n  install_unit "$ROOT_DIR/deploy/systemd/monchk-disk-alert.timer" "$SYSTEMD_DIR/$TIMER_NAME"\n''', '''  install_unit "$ROOT_DIR/deploy/systemd/monchk-disk-alert.service" "$SYSTEMD_DIR/$SERVICE_NAME"\n  install_unit "$ROOT_DIR/deploy/systemd/monchk-disk-alert.timer" "$SYSTEMD_DIR/$TIMER_NAME"\n  install_unit "$ROOT_DIR/deploy/systemd/monchk-disk-alert-heartbeat.service" "$SYSTEMD_DIR/$HEARTBEAT_SERVICE_NAME"\n  install_unit "$ROOT_DIR/deploy/systemd/monchk-disk-alert-heartbeat.timer" "$SYSTEMD_DIR/$HEARTBEAT_TIMER_NAME"\n''')
s = s.replace('''  systemctl enable --now "$TIMER_NAME"\n  log "func=reload_and_enable success timer=$TIMER_NAME"\n''', '''  systemctl enable --now "$TIMER_NAME"\n  systemctl enable --now "$HEARTBEAT_TIMER_NAME"\n  log "func=reload_and_enable success timer=$TIMER_NAME heartbeat_timer=$HEARTBEAT_TIMER_NAME"\n''')
p.write_text(s)

Path('deploy/systemd/monchk-disk-alert-heartbeat.service').write_text('''[Unit]\nDescription=Send heartbeat for disk Bark alert pipeline\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=oneshot\nUser=admin\nWorkingDirectory=/home/admin/ops-repos/monitor-server-data-check-skills\nEnvironmentFile=/home/admin/.config/monchk/disk-alert.env\nExecStart=/home/admin/ops-repos/monitor-server-data-check-skills/bin/run diagnose-disk-bark-heartbeat ${TARGET_HOST} ${DISK_ALERT_THRESHOLD}\n''')
Path('deploy/systemd/monchk-disk-alert-heartbeat.timer').write_text('''[Unit]\nDescription=Run disk Bark alert heartbeat daily\n\n[Timer]\nOnCalendar=*-*-* 09:00:00\nPersistent=true\nUnit=monchk-disk-alert-heartbeat.service\n\n[Install]\nWantedBy=timers.target\n''')

# README append small section if not exists
p = Path('README.md')
s = p.read_text()
if 'diagnose-disk-bark-heartbeat' not in s:
    s += '''\n\n## 磁盘 Bark 告警心跳\n\n- `./bin/run diagnose-disk-bark [host] [threshold]`：磁盘超过阈值时发送告警。\n- `./bin/run diagnose-disk-bark-heartbeat [host] [threshold]`：主动发送心跳，用于验证 Bark 通知链路仍可达。\n- systemd：`monchk-disk-alert.timer` 每 15 分钟巡检；`monchk-disk-alert-heartbeat.timer` 每天 09:00 发送一次心跳。\n- 可选备用通道：在 `/home/admin/.config/monchk/disk-alert.env` 配置 `BARK_SECONDARY_KEY`、`BARK_SECONDARY_SERVER`、`BARK_SECONDARY_PROXY`、`BARK_SECONDARY_GROUP`。不要把密钥写入仓库。\n'''
p.write_text(s)
