#!/usr/bin/env bash
# skill-compliance-check.sh — Skill 合规门禁
# 检查本次改动是否经过了 SKILL-REGISTRY.md 中对应 skill 的规则
# 用法：
#   ./scripts/skill-compliance-check.sh [--change <name>] [--ci]
#   --change  指定 change 名（默认从 .opsx-active-change 读取）
#   --ci      CI 模式，检查 git diff 而非暂存区
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"

REGISTRY=".cursor/skills/SKILL-REGISTRY.md"
CHANGE_DIR_PREFIX="openspec/changes"
ACTIVE_CHANGE_FILES=('.opsx-active-change' '.poquan-active-change')

log() { printf '[skill-compliance] %s\n' "$*"; }
warn() { printf '[skill-compliance] WARN: %s\n' "$*"; }
die() { printf '[skill-compliance] ERROR: %s\n' "$*"; exit 1; }

# ── 解析参数 ──
CHANGE_NAME=""
CI_MODE=false
while [[ $# -gt 0 ]]; do
  case "$1" in
    --change) CHANGE_NAME="$2"; shift 2 ;;
    --ci) CI_MODE=true; shift ;;
    *) shift ;;
  esac
done

# ── 跳过条件 ──
if [[ "${OPSX_SKIP_OPSX:-}" == "1" ]] || [[ "${POQUAN_SKIP_OPSX:-}" == "1" ]]; then
  log "已跳过（OPSX_SKIP_OPSX=1）"
  exit 0
fi

if [[ ! -f "$REGISTRY" ]]; then
  warn "SKILL-REGISTRY.md 不存在，跳过 skill 合规检查"
  exit 0
fi

# ── 解析 change 名 ──
if [[ -z "$CHANGE_NAME" ]]; then
  if [[ -n "${OPSX_ACTIVE_CHANGE:-}" ]]; then
    CHANGE_NAME="$OPSX_ACTIVE_CHANGE"
  elif [[ -n "${POQUAN_ACTIVE_CHANGE:-}" ]]; then
    CHANGE_NAME="$POQUAN_ACTIVE_CHANGE"
  else
    for f in "${ACTIVE_CHANGE_FILES[@]}"; do
      if [[ -f "$f" ]]; then
        CHANGE_NAME="$(tr -d '[:space:]' <"$f")"
        [[ -n "$CHANGE_NAME" ]] && break
      fi
    done
  fi
fi

if [[ -z "$CHANGE_NAME" ]]; then
  warn "未找到活跃 change，跳过 skill 合规检查"
  exit 0
fi

# ── 收集本次改动文件 ──
CHANGED_FILES=()
if [[ "$CI_MODE" == "true" ]]; then
  local base="${GITHUB_BASE_REF:-main}"
  base="${base#origin/}"
  git fetch origin "$base" --depth=1 2>/dev/null || true
  local merge_base
  merge_base="$(git merge-base "origin/${base}" HEAD 2>/dev/null || git merge-base "${base}" HEAD 2>/dev/null || echo "")"
  [[ -n "$merge_base" ]] || merge_base="HEAD~1"
  while IFS= read -r line; do
    [[ -n "$line" ]] && CHANGED_FILES+=("$line")
  done < <(git diff --name-only "$merge_base"...HEAD 2>/dev/null || git diff --name-only HEAD~1 HEAD)
else
  while IFS= read -r line; do
    [[ -n "$line" ]] && CHANGED_FILES+=("$line")
  done < <(git diff --cached --name-only --diff-filter=ACMR 2>/dev/null || true)
  if [[ ${#CHANGED_FILES[@]} -eq 0 ]]; then
    while IFS= read -r line; do
      [[ -n "$line" ]] && CHANGED_FILES+=("$line")
    done < <(git diff --name-only --diff-filter=ACMR HEAD 2>/dev/null || true)
  fi
fi

if [[ ${#CHANGED_FILES[@]} -eq 0 ]]; then
  log "无改动文件，跳过"
  exit 0
fi

# ── 定义文件路径 → skill 映射（与 SKILL-REGISTRY.md 一致）──
declare -A FILE_SKILL_MAP=(
  ["src/components/layout/config/layout.config.ts"]="fe-layout-first-level-route"
  ["src/components/layout/src/layout-teambition.vue"]="fe-layout-first-level-route"
  ["src/config/router/index.ts"]="fe-layout-first-level-route"
  ["src/config/api/modules/"]="fe-new-api"
  ["src/config/api/request.ts"]="fe-api-call-style"
  ["src/views/"]="fe-new-page"
  ["src/components/"]="fe-component"
)

# ── 检查 tasks.md 中的 skill 标记 ──
TASKS_FILE="${CHANGE_DIR_PREFIX}/${CHANGE_NAME}/tasks.md"
SKILLS_IN_TASKS=()

if [[ -f "$TASKS_FILE" ]]; then
  # 提取所有 <!-- skill:xxx,yyy --> 标记
  while IFS= read -r skill_list; do
    IFS=',' read -ra skills <<< "$skill_list"
    for s in "${skills[@]}"; do
      s="$(echo "$s" | xargs)"
      [[ -n "$s" ]] && SKILLS_IN_TASKS+=("$s")
    done
  done < <(grep -oP '<!-- skill:\K[^-]+(?= -->)' "$TASKS_FILE" 2>/dev/null || true)
fi

# ── 按改动文件推断需要的 skill ──
REQUIRED_SKILLS=()
for file in "${CHANGED_FILES[@]}"; do
  for pattern in "${!FILE_SKILL_MAP[@]}"; do
    if [[ "$file" == *"$pattern"* ]]; then
      skill="${FILE_SKILL_MAP[$pattern]}"
      # 去重
      found=false
      for existing in "${REQUIRED_SKILLS[@]}"; do
        if [[ "$existing" == "$skill" ]]; then found=true; break; fi
      done
      if [[ "$found" == "false" ]]; then
        REQUIRED_SKILLS+=("$skill")
      fi
    fi
  done
done

# ── 检查：需要的 skill 是否在 tasks.md 标记中 ──
VIOLATIONS=0
for required in "${REQUIRED_SKILLS[@]}"; do
  found=false
  for declared in "${SKILLS_IN_TASKS[@]}"; do
    if [[ "$declared" == "$required" ]]; then found=true; break; fi
  done
  if [[ "$found" == "false" ]]; then
    warn "改动涉及需要 $required 的文件，但 tasks.md 中未声明该 skill 标记"
    VIOLATIONS=$((VIOLATIONS+1))
  fi
done

# ── 检查：关键 skill 的规则是否被遵循（文件存在性检查）──
# 检查1：改了 router 但没改 layout.config.ts → fe-layout-first-level-route 未执行
ROUTER_CHANGED=false
LAYOUT_CHANGED=false
for file in "${CHANGED_FILES[@]}"; do
  [[ "$file" == *"src/config/router/index.ts"* ]] && ROUTER_CHANGED=true
  [[ "$file" == *"src/components/layout/config/layout.config.ts"* ]] && LAYOUT_CHANGED=true
done

if [[ "$ROUTER_CHANGED" == "true" ]] && [[ "$LAYOUT_CHANGED" == "false" ]]; then
  # 检查是否新增了一级路由（包含 menu 属性的路由）
  if git diff --cached --name-only --diff-filter=ACMR 2>/dev/null | grep -q "router/index.ts" || \
     git diff --name-only --diff-filter=ACMR HEAD 2>/dev/null | grep -q "router/index.ts"; then
    # 检查 diff 中是否有新增的 meta.menu（一级菜单标志）
    NEW_MENU=$(git diff HEAD -- src/config/router/index.ts 2>/dev/null | grep "^+" | grep -c "meta.*menu" || echo "0")
    if [[ "$NEW_MENU" -gt 0 ]]; then
      warn "新增了路由 meta.menu 但未修改 layout.config.ts — fe-layout-first-level-route 可能未执行"
      warn "这会导致：路由存在但左侧菜单不显示"
      VIOLATIONS=$((VIOLATIONS+1))
    fi
  fi
fi

# 检查2：改了 layout.config.ts 但没改 default-expanded-keys
TEAMBITION_CHANGED=false
for file in "${CHANGED_FILES[@]}"; do
  [[ "$file" == *"layout-teambition.vue"* ]] && TEAMBITION_CHANGED=true
done

if [[ "$LAYOUT_CHANGED" == "true" ]] && [[ "$TEAMBITION_CHANGED" == "false" ]]; then
  # 检查 diff 中是否新增了 menuList 顶层项（一级菜单）
  NEW_TOP_MENU=$(git diff HEAD -- src/components/layout/config/layout.config.ts 2>/dev/null | grep "^+" | grep -c "menuNum" || echo "0")
  if [[ "$NEW_TOP_MENU" -gt 0 ]]; then
    warn "新增了 menuList 顶层项但未修改 layout-teambition.vue 的 default-expanded-keys — fe-layout-first-level-route 可能未完整执行"
    warn "这会导致：新一级菜单默认折叠，用户误以为菜单未配上"
    VIOLATIONS=$((VIOLATIONS+1))
  fi
fi

# ── 结果 ──
if [[ $VIOLATIONS -gt 0 ]]; then
  die "发现 $VIOLATIONS 个 skill 合规违规。请在 tasks.md 中补充对应 skill 标记，并按 skill 规则重新执行改动。详见 .cursor/skills/SKILL-REGISTRY.md"
else
  log "OK — skill 合规检查通过（需要: ${REQUIRED_SKILLS[*]:-无}, 已声明: ${SKILLS_IN_TASKS[*]:-无}）"
fi
