#!/bin/bash
# Cocos Web 构建 → 001code-html 可用的 unity 静态资源 + CDN 上传清单
#
# 001code-html 加载约定（scratch-gui/src/components/stage-unity/stage-unity.jsx）:
#   本地 loader:  /unity/Build/mstest5.loader.js        （不走 CDN，须放 static/unity/Build/）
#   CDN 资源:     {unitycdndir}/Build/*.br
#                 {unitycdndir}/StreamingAssets/aa/...
#
# 用法:
#   bash tools/deploy-to-001code.sh
#   bash tools/deploy-to-001code.sh --build build/web-desktop
#   bash tools/deploy-to-001code.sh --code-html /path/to/001code-html
#   bash tools/deploy-to-001code.sh --skip-pack   # 仅用已有 build/mstest5 同步

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

BUILD_DIR="$PROJECT_DIR/build/web-desktop"
PACK_DIR="$PROJECT_DIR/build/mstest5"
CODE_HTML="/Users/liuyufei/tfrh/001code/001code-html"
UNITY_STATIC=""
UNITY_REF=""
CDN_BASE=""
SKIP_PACK=0
DRY_RUN=0
CDN_UPLOAD_ONLY=0
CDN_PURE=0

while [[ $# -gt 0 ]]; do
  case "$1" in
    --build) BUILD_DIR="$2"; shift 2 ;;
    --pack) PACK_DIR="$2"; shift 2 ;;
    --code-html) CODE_HTML="$2"; shift 2 ;;
    --unity-static) UNITY_STATIC="$2"; shift 2 ;;
    --unity-ref) UNITY_REF="$2"; shift 2 ;;
    --cdn-base) CDN_BASE="$2"; shift 2 ;;
    --skip-pack) SKIP_PACK=1; shift ;;
    --cdn-upload-only) CDN_UPLOAD_ONLY=1; shift ;;
    --cdn-pure) CDN_PURE=1; shift ;;
    --dry-run) DRY_RUN=1; shift ;;
    -h|--help)
      cat <<'EOF'
Usage: deploy-to-001code.sh [options]

将 Cocos 包部署到 001code-html/scratch-gui/static/unity/，并生成 CDN 上传清单。

选项:
  --build DIR         Cocos Web Desktop 构建目录（默认 build/web-desktop）
  --pack DIR          package-for-cdn 输出目录（默认 build/mstest5）
  --code-html DIR     001code-html 根目录
  --unity-static DIR  覆盖 static/unity 目标（默认 scratch-gui/static/unity）
  --unity-ref DIR     catalog 参考包（默认 static/unity，否则 竞赛/mstest5）
  --cdn-base URL      覆盖 CDN 根 URL（默认从 config.js 读取 unitycdndir）
  --skip-pack         跳过打包，直接同步已有 --pack 目录
  --cdn-upload-only   只打包运行时包 + 清单，不同步 static/unity
  --cdn-pure          不同步/不解压到 static/unity（纯 CDN，loader 也走 OSS）
  --dry-run           只打印将执行的 rsync，不写入

步骤:
  1. package-for-cdn（以 001code static/unity 的 catalog 为参考）
  2. rsync Build/、StreamingAssets/ → scratch-gui/static/unity/
  3. 生成 build/deploy-001code-cdn-manifest.txt

部署后请在 001code-html/scratch-gui 执行 npm run build，或 npm start 本地验证。
EOF
      exit 0
      ;;
    *) echo "Unknown option: $1"; exit 1 ;;
  esac
done

CODE_HTML="$(cd "$CODE_HTML" 2>/dev/null && pwd || true)"
if [[ -z "$CODE_HTML" || ! -d "$CODE_HTML/scratch-gui" ]]; then
  echo "Error: 001code-html 不存在: $CODE_HTML"
  exit 1
fi

if [[ -z "$UNITY_STATIC" ]]; then
  UNITY_STATIC="$CODE_HTML/scratch-gui/static/unity"
fi
UNITY_STATIC="$(cd "$UNITY_STATIC" 2>/dev/null && pwd || true)"
if [[ -z "$UNITY_STATIC" ]]; then
  echo "Error: static/unity 不存在，请先创建: $CODE_HTML/scratch-gui/static/unity"
  exit 1
fi

mkdir -p "$UNITY_STATIC/Build" "$UNITY_STATIC/StreamingAssets"

# package-for-cdn 需要完整 Unity 参考包（index.html + TemplateData + catalog）
# static/unity 是 Cocos 扁平运行包，仅有 catalog 时不能作为参考
DEFAULT_UNITY_REF="${UNITY_REF:-$HOME/tfrh/竞赛/mstest5}"
UNITY_REF_DIR="$(cd "$DEFAULT_UNITY_REF" 2>/dev/null && pwd || true)"

if [[ -z "$UNITY_REF" && -f "$UNITY_STATIC/index.html" && -f "$UNITY_STATIC/StreamingAssets/aa/catalog.json" ]]; then
  UNITY_REF_DIR="$UNITY_STATIC"
  echo ">>> catalog 参考: static/unity（完整 Unity 包）"
elif [[ -f "$UNITY_REF_DIR/StreamingAssets/aa/catalog.json" ]]; then
  echo ">>> catalog 参考: $UNITY_REF_DIR"
else
  echo "Error: 缺少 Unity 参考包（须含 index.html 与 StreamingAssets/aa/catalog.json）" >&2
  echo "       默认路径: $DEFAULT_UNITY_REF" >&2
  echo "       可指定: bash tools/deploy-cdn.sh 所在脚本加 --unity-ref /path/to/mstest5" >&2
  exit 1
fi

if [[ "$SKIP_PACK" -eq 0 ]]; then
  BUILD_DIR="$(cd "$BUILD_DIR" 2>/dev/null && pwd || true)"
  if [[ -z "$BUILD_DIR" || ! -f "$BUILD_DIR/index.html" ]]; then
    echo "Error: 请先 Cocos Creator 构建 Web Desktop: $BUILD_DIR"
    exit 1
  fi
  if [[ ! -f "$UNITY_REF_DIR/StreamingAssets/aa/catalog.json" ]]; then
    echo "Error: 缺少参考 catalog: $UNITY_REF_DIR/StreamingAssets/aa/catalog.json"
    echo "       请指定 --unity-ref 指向含 StreamingAssets/aa/catalog.json 的 Unity 包"
    exit 1
  fi
  echo ">>> [1/3] 打包 (unity-ref = $UNITY_REF_DIR)"
  node "$SCRIPT_DIR/package-for-cdn.js" "$BUILD_DIR" "$PACK_DIR" "$UNITY_REF_DIR"
else
  PACK_DIR="$(cd "$PACK_DIR" 2>/dev/null && pwd || true)"
  if [[ -z "$PACK_DIR" || ! -f "$PACK_DIR/Build/mstest5.loader.js" ]]; then
    echo "Error: --skip-pack 但打包目录无效: $PACK_DIR"
    exit 1
  fi
  echo ">>> [1/3] 跳过打包，使用: $PACK_DIR"
fi

PACK_DIR="$(cd "$PACK_DIR" && pwd)"

if [[ -z "$CDN_BASE" ]]; then
  CONFIG_JS="$CODE_HTML/scratch-gui/src/playground/config.js"
  if [[ -f "$CONFIG_JS" ]]; then
    CDN_BASE="$(node -e "
      const fs=require('fs');
      const t=fs.readFileSync(process.argv[1],'utf8');
      const m=t.match(/unitycdndir:\s*['\"]([^'\"]+)['\"]/);
      if(!m){process.exit(1)}
      console.log(m[1]);
    " "$CONFIG_JS" 2>/dev/null || true)"
  fi
fi
CDN_BASE="${CDN_BASE:-https://oss.eanic.cn/001_code_unity_res_CHANGE_ME}"

CDN_DEPLOY_DIR="$PROJECT_DIR/build/deploy"
if [[ "$DRY_RUN" -eq 1 ]]; then
  echo ">>> [1b] [dry-run] 生成上传清单 → $CDN_DEPLOY_DIR"
else
  echo ">>> [1b] 生成上传清单（运行时包不复制: $PACK_DIR）"
  MANIFEST_ARGS=("$PACK_DIR" --manifest-dir "$CDN_DEPLOY_DIR")
  [[ -n "$CDN_BASE" ]] && MANIFEST_ARGS+=(--cdn-base "$CDN_BASE")
  node "$SCRIPT_DIR/write-deploy-manifest.js" "${MANIFEST_ARGS[@]}"
fi

if [[ "$CDN_UPLOAD_ONLY" -eq 1 ]]; then
  echo ""
  echo "完成（仅运行时包 + 清单）。"
  echo "  运行时包: $PACK_DIR"
  echo "  清单:     $CDN_DEPLOY_DIR/UPLOAD-MANIFEST.txt"
  exit 0
fi

if [[ "$CDN_PURE" -eq 1 ]]; then
  echo ">>> [2/3] 跳过 static/unity 同步（--cdn-pure，仅 OSS）"
else
  echo ">>> [2/3] 同步到 static/unity（与运行时包相同）"
  if [[ "$DRY_RUN" -eq 1 ]]; then
    DRY_RUN=1 bash "$SCRIPT_DIR/sync-unity-package-to-static.sh" "$PACK_DIR" "$UNITY_STATIC"
  else
    bash "$SCRIPT_DIR/sync-unity-package-to-static.sh" "$PACK_DIR" "$UNITY_STATIC"
  fi
fi

MANIFEST="$PROJECT_DIR/build/deploy-001code-cdn-manifest.txt"
mkdir -p "$(dirname "$MANIFEST")"

echo ">>> [3/3] 生成 CDN 上传清单: $MANIFEST"
{
  echo "# 001code-html CDN 上传清单"
  echo "# 生成时间: $(date -u '+%Y-%m-%dT%H:%M:%SZ')"
  echo "# CDN 根目录 (unitycdndir): $CDN_BASE"
  echo "#"
  echo "# 上传规则: 将 build/mstest5/ 全部内容上传到 OSS unitycdndir"
  echo ""
  echo "## CDN: Build/（unitycdnbuilddir = unitycdndir + /Build，含 loader.js）"
  for f in "$PACK_DIR/Build"/*; do
    [[ -f "$f" ]] || continue
    base="$(basename "$f")"
    echo "local: Build/$base"
    echo "cdn:   $CDN_BASE/Build/$base"
    echo ""
  done
  echo "## CDN: StreamingAssets/（unitycdndir + /StreamingAssets）"
  while IFS= read -r -d '' f; do
    rel="${f#$PACK_DIR/StreamingAssets/}"
    echo "local: StreamingAssets/$rel"
    echo "cdn:   $CDN_BASE/StreamingAssets/$rel"
    echo ""
  done < <(find "$PACK_DIR/StreamingAssets" -type f ! -name '.DS_Store' -print0 | sort -z)
  for db in levels-database.json levels-database.json.br; do
    if [[ -f "$PACK_DIR/$db" ]]; then
      echo "local: $db"
      echo "cdn:   $CDN_BASE/$db"
      echo ""
    fi
  done
  echo "## 001code config.js 当前配置"
  echo "unitycdndir:      $CDN_BASE"
  echo "unitycdnbuilddir: $CDN_BASE/Build"
  echo "streamingAssetsUrl (CDN): $CDN_BASE/StreamingAssets"
  echo "loaderUrl (CDN):  $CDN_BASE/Build/mstest5.loader.js"
  echo ""
  echo "## 验证（上传后）"
  echo "curl -I \"$CDN_BASE/Build/mstest5.loader.js\""
  echo "curl -I \"$CDN_BASE/StreamingAssets/aa/catalog.json\""
  python3 - <<'PY' "$PACK_DIR/StreamingAssets/aa/catalog.json" "$CDN_BASE"
import json, sys
catalog_path, cdn = sys.argv[1], sys.argv[2].rstrip('/')
d = json.load(open(catalog_path))
names = sorted({x.split('/')[-1] for x in d.get('m_InternalIds', []) if '.bundle' in x})
for n in names:
    print(f'curl -I "{cdn}/StreamingAssets/aa/WebGL/{n}"')
PY
} > "$MANIFEST"

echo ""
echo "完成。"
if [[ "$CDN_PURE" -eq 1 ]]; then
  echo "  模式: 纯 CDN（未写入 static/unity）"
else
  echo "  本地 static: $UNITY_STATIC"
fi
echo "  CDN 运行时包:  $PACK_DIR"
echo "  CDN 清单:      $CDN_DEPLOY_DIR/UPLOAD-MANIFEST.txt"
echo ""
echo "下一步:"
echo "  cd \"$CODE_HTML/scratch-gui\""
if [[ "$CDN_PURE" -eq 1 ]]; then
  echo "  config.js: usecdn:true → npm run build → 部署 dist/（无需 static/unity 游戏资源）"
else
  echo "  npm start          # usecdn:false 本地测 static/unity"
  echo "  npm run build      # usecdn:true 生产构建"
fi
echo ""
echo "生产 CDN: 上传 $PACK_DIR 全部内容到 OSS（见 deploy/UPLOAD-MANIFEST.txt）"
