#!/bin/sh
# 来伊份团队 pre-commit 钩子
# 对应《来伊份工作流约束规范 §3.3》自动化执法工具
# 对应《来伊份自检清单》核心可自动化检查项
# 由 lyf-rules 自动生成，手动修改可能被覆盖

echo "🔍 [来伊份] 运行 pre-commit 检查..."

# --------------------------------------------------
# 完整性校验：SHA256 自校验
# --------------------------------------------------
SELF_HASH="__LYF_INSTALL_HASH__"

self_check() {
  local script_body
  script_body=$(grep -v '^SELF_HASH=' "$0" 2>/dev/null)
  local actual_hash
  actual_hash=$(printf '%s' "$script_body" | shasum -a 256 2>/dev/null | cut -d' ' -f1)
  if [ "$actual_hash" != "$SELF_HASH" ]; then
    echo "  ❌ 完整性校验失败：pre-commit 已被篡改"
    echo "     └─ 请运行 lyf-rules hooks --overwrite 修复"
    exit 1
  fi
}
self_check

# --------------------------------------------------
# 文件完整性校验：检查所有已安装的规则和钩子文件
# --------------------------------------------------
MANIFEST=".lyf-checksums.json"
if [ -f "$MANIFEST" ]; then
  echo "   ├─ 校验文件完整性..."

  if command -v python3 >/dev/null 2>&1; then
    checker=$(python3 -c "
import json, sys
try:
    with open('$MANIFEST') as f:
        m = json.load(f)
    import hashlib, os
    failed = 0
    for path, expected in m.get('files', {}).items():
        if os.path.exists(path):
            actual = hashlib.sha256(open(path, 'rb').read()).hexdigest()
            if actual != expected:
                print(f'  ❌ 文件已被篡改: {path}')
                failed += 1
    sys.exit(failed)
except Exception as e:
    print(f'  ⚠  校验异常: {e}')
    sys.exit(1)
" 2>&1)
    result=$?
    if [ $result -ne 0 ]; then
      echo "$checker"
      echo "     └─ 请运行 lyf-rules init --yes --hooks --overwrite 修复"
      exit 1
    fi
  elif command -v node >/dev/null 2>&1; then
    checker=$(node -e "
const fs = require('fs');
const crypto = require('crypto');
try {
  const m = JSON.parse(fs.readFileSync('$MANIFEST', 'utf-8'));
  let failed = 0;
  for (const [p, expected] of Object.entries(m.files || {})) {
    if (fs.existsSync(p)) {
      const actual = crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex');
      if (actual !== expected) {
        console.log('  ❌ 文件已被篡改: ' + p);
        failed++;
      }
    }
  }
  process.exit(failed);
} catch(e) {
  console.log('  ⚠  校验异常: ' + e.message);
  process.exit(1);
}
" 2>&1)
    result=$?
    if [ $result -ne 0 ]; then
      echo "$checker"
      echo "     └─ 请运行 lyf-rules init --yes --hooks --overwrite 修复"
      exit 1
    fi
  fi
  echo "   ├─ ✅ 文件完整性校验通过"
fi

# --------------------------------------------------
# 配置区：按项目实际目录修改
# --------------------------------------------------
SCAN_BASE="src/main/java"

# --------------------------------------------------
# 自检脚本：检查常见编码违规
# CO-08 日志规范 | CO-09 空值安全 | CO-10 魔法值 | CO-12 注释同步
# SE-01 注入防护 | SE-07 密钥管理
# --------------------------------------------------
self_check() {
  echo "   ├─ 运行自检..."

  # CO-08: System.out 检查
  sout=$(find $SCAN_BASE -name "*.java" -not -path "*/build/*" 2>/dev/null \
    | xargs grep -n "System\.out\.\(print\|println\)" 2>/dev/null \
    | grep -v "example\s*=" | head -5)
  if [ -n "$sout" ]; then
    echo "  ❌ CO-08: 发现 System.out.println（请用日志框架）"
    echo "$sout" | sed 's/^/       /'
  fi

  # SE-07: 硬编码密钥检查
  secret=$(find $SCAN_BASE -name "*.java" -not -path "*/build/*" 2>/dev/null \
    | xargs grep -n "password\s*=\|secret\s*=\|apiKey\s*=\|api_secret\s*=\|accessKey\s*=" 2>/dev/null \
    | grep -v "example\s*=" | grep -v "//" | grep -v "\.env\|getenv\|System\.getenv\|@Value" | head -5)
  if [ -n "$secret" ]; then
    echo "  ❌ SE-07: 发现疑似硬编码密钥/密码"
    echo "$secret" | sed 's/^/       /'
  fi

  # CO-09: NPE 风险检查
  npe=$(find $SCAN_BASE -name "*.java" -not -path "*/build/*" 2>/dev/null \
    | xargs grep -n "\.get(" 2>/dev/null \
    | grep -v "Optional" | grep -v "@" | grep -v "//" | head -5)
  if [ -n "$npe" ]; then
    echo "  ⚠  CO-09: 发现直接 .get() 调用（可能有 NPE 风险）"
    echo "$npe" | sed 's/^/       /'
  fi

  # CO-12: 残留 TODO/FIXME
  todo=$(find $SCAN_BASE -name "*.java" -not -path "*/build/*" 2>/dev/null \
    | xargs grep -n "TODO\|FIXME\|HACK\|XXX" 2>/dev/null \
    | grep -v "example\s*=" | head -10)
  if [ -n "$todo" ]; then
    echo "  ⚠  CO-12: 发现未处理的 TODO/FIXME 标记"
    echo "$todo" | sed 's/^/       /'
  fi

  echo "   ├─ ✅ 自检完成"
}

# --------------------------------------------------
# TypeScript 类型检查
# --------------------------------------------------
tsc_check() {
  if [ -f "tsconfig.json" ] && command -v npx >/dev/null 2>&1; then
    echo "   ├─ 类型检查 (tsc)..."
    npx tsc --noEmit 2>&1
    if [ $? -ne 0 ]; then
      echo "   └─ ❌ 类型检查失败，请修复后重新提交"
      exit 1
    fi
    echo "   ├─ ✅ 类型检查通过"
  fi
}

# --------------------------------------------------
# 执行检查序列
# --------------------------------------------------
self_check
tsc_check

# 测试（不阻塞，仅提醒）
if [ -f "vitest.config.ts" ] || [ -d "test" ] || [ -d "__tests__" ]; then
  echo "   ├─ 运行测试..."
  if command -v npx >/dev/null 2>&1; then
    npx vitest run --reporter=verbose 2>&1 || true
  fi
fi

echo "   └─ ✅ pre-commit 检查完成"