#!/bin/sh
# 来伊份团队 pre-push 钩子
# 对应《来伊份工作流约束规范 §4》分支策略
# 对应《来伊份工作流约束规范 §3.3》自动化执法工具
# 由 lyf-rules 自动生成

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

# --------------------------------------------------
# 文件完整性校验：检查所有已安装的规则和钩子文件
# --------------------------------------------------
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

# --------------------------------------------------
# 编码自检（对应 lyf-self-check-list）
# --------------------------------------------------
SCAN_BASE="src/main/java"
echo "   ├─ 运行编码自检..."

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

secret=$(find $SCAN_BASE -name "*.java" -not -path "*/build/*" 2>/dev/null \
  | xargs grep -n "password\s*=\|secret\s*=\|apiKey\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

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

echo "   ├─ ✅ 编码自检完成"

# --------------------------------------------------
# 分支保护：禁止直接推送到 main/master
# --------------------------------------------------
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$current_branch" = "main" ] || [ "$current_branch" = "master" ]; then
  echo "   └─ ❌ 禁止直接推送至 $current_branch 分支"
  echo "      请通过 feature -> develop -> release -> main 流程合并"
  exit 1
fi

# --------------------------------------------------
# 运行全量测试
# --------------------------------------------------
echo "   ├─ 运行全量测试..."
if command -v npx >/dev/null 2>&1; then
  if [ -f "vitest.config.ts" ] || [ -f "jest.config.js" ]; then
    echo "   ├─ 运行单元测试..."
    if [ -f "vitest.config.ts" ]; then
      npx vitest run 2>&1
    elif [ -f "jest.config.js" ]; then
      npx jest --passWithNoTests 2>&1
    fi
    if [ $? -ne 0 ]; then
      echo "   └─ ❌ 测试未通过，请修复后推送"
      exit 1
    fi
  fi
fi

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