#!/usr/bin/env bash
# ============================================================
# 自动下载 Civitai 模型: Qwen-Image-2.1 Edit LoRA (Nude Edit)
# 模型: https://civitai.red/models/2956565
# 版本 v1.0 / 文件: Qwen-Image-2.1 NSFW Image Edit.safetensors (82MB)
# Early Access 到期: 2026-09-25T12:49:39Z (= 本地 2026-09-25 20:49:39)
# 到期后用 API key 走 civitai.red 下载, 签名 URL 直下, SHA256 校验
# 由 systemd transient 服务启动; 日志见同目录 .log
# ============================================================
set -uo pipefail

OUT_DIR="/home/zyw/Downloads/xunlei-downloads"
OUT="$OUT_DIR/Qwen-Image-2.1 NSFW Image Edit.safetensors"
LOG="$OUT_DIR/qwen-image-21-edit-lora-download.log"
KEY_FILE="/home/zyw/Downloads/civitai_api_key.txt"
API_URL="https://civitai.red/api/download/models/3349092?fileId=3236195"
PROXY="http://127.0.0.1:10809"   # 签名 URL 落在 b2.civitai.com，本机 DNS 被污染，必须走 v2ray 代理
EXPECTED_SIZE=83943552
EXPECTED_SHA256="9C143CBFE7B016EFDCE7499506C02D0BFA1842AE6524BB64E05888F2E325E67A"
DEADLINE_EPOCH=$(date -d '2026-09-25T12:49:39Z' +%s)
MAX_ATTEMPTS=48          # 48 × 5 分钟 ≈ 4 小时重试窗口

log() { echo "[$(date '+%F %T %z')] $*" >> "$LOG"; }

log "=== 任务启动 pid=$$ ==="

# ---- 0. 幂等：已完成则直接退出；并自清理 crontab 兜底条目 ----
if [ -f "$OUT" ]; then
  S=$(sha256sum "$OUT" | awk '{print $1}')
  if [ "${S,,}" = "${EXPECTED_SHA256,,}" ]; then
    log "文件已存在且校验通过，无需重复下载: $OUT"
    crontab -l 2>/dev/null | grep -v 'qwen-image-21-edit-lora-auto-dl' | crontab - 2>/dev/null || true
    exit 0
  fi
fi

# ---- 1. 等到期（防计时器提前触发） ----
NOW=$(date +%s)
if [ "$NOW" -lt "$DEADLINE_EPOCH" ]; then
  WAIT=$((DEADLINE_EPOCH - NOW + 120))
  log "Early Access 尚未到期 (差 $((WAIT/60)) 分钟)，先 sleep 等待 (约 $((WAIT/3600)) 小时)"
  sleep "$WAIT"
fi

# ---- 2. 重试下载 ----
[ -f "$KEY_FILE" ] || { log "!!! 找不到 API key: $KEY_FILE"; exit 1; }
KEY=$(cat "$KEY_FILE")

ok=0
for i in $(seq 1 "$MAX_ATTEMPTS"); do
  log "第 $i/$MAX_ATTEMPTS 次尝试: $API_URL"
  rm -f "$OUT.part"

  # 2a. 拿响应头（Early Access 未过 → 403 JSON；已过 → 302 到签名 B2 URL）
  HDR=$(curl -s --noproxy '*' -m 120 -D - -o /dev/null -H "Authorization: Bearer $KEY" "$API_URL")
  CODE=$(echo "$HDR" | head -1 | awk '{print $2}')
  LOC=$(echo "$HDR" | tr -d '\r' | grep -i '^location:' | sed 's/^[Ll]ocation: //' | tail -1)
  log "HTTP=$CODE location=${LOC:0:100}"

  if [ -n "$LOC" ]; then
    # 2b. 从签名 URL 下载：优先走 v2ray 代理（b2.civitai.com 本机 DNS 污染），再试直连兜底
    for MODE in proxy direct; do
      if [ "$MODE" = "proxy" ]; then
        curl -sL -x "$PROXY" --connect-timeout 20 -m 1800 -C - -o "$OUT.part" "$LOC"
      else
        curl -sL --noproxy '*' --connect-timeout 8 -m 120 -C - -o "$OUT.part" "$LOC"
      fi
      CURL_CODE=$?
      SZ=$(stat -c %s "$OUT.part" 2>/dev/null || echo 0)
      log "  传输[$MODE] rc=$CURL_CODE size=$SZ"
      [ "$SZ" -eq "$EXPECTED_SIZE" ] && break
    done
  elif [ "$CODE" = "200" ]; then
    curl -sL -x "$PROXY" --connect-timeout 20 -m 1800 -o "$OUT.part" "$API_URL"
    CURL_CODE=$?
  else
    CURL_CODE=1
  fi

  SIZE=$(stat -c %s "$OUT.part" 2>/dev/null || echo 0)
  log "curl_rc=$CURL_CODE size=$SIZE (期望 $EXPECTED_SIZE)"

  if [ "$CURL_CODE" = "0" ] && [ "$SIZE" -eq "$EXPECTED_SIZE" ]; then
    ok=1; break
  fi
  rm -f "$OUT.part"
  log "未就绪，5 分钟后重试"
  sleep 300
done

if [ "$ok" != "1" ]; then
  log "!!! 下载最终失败（$MAX_ATTEMPTS 次尝试后仍未成功），请人工检查"
  exit 1
fi

# ---- 3. SHA256 校验并落盘 ----
SHA=$(sha256sum "$OUT.part" | awk '{print $1}')
log "SHA256=$SHA"
# 注意：sha256sum 输出小写、Civitai API 返回大写 → 必须忽略大小写比较
if [ "${SHA,,}" = "${EXPECTED_SHA256,,}" ]; then
  mv "$OUT.part" "$OUT"
  log "=== ✅ 下载完成且校验通过: $OUT ($SIZE bytes) ==="
  log "=== 模型页: https://civitai.red/models/2956565 ==="
  exit 0
else
  log "!!! SHA256 不匹配！期望 $EXPECTED_SHA256，保留 .part 供排查"
  exit 1
fi
