#!/bin/bash

# Code Quality Validation Script
# Enforces CODE_QUALITY_PROTOCOL.md rules
# Run before every commit

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

ERRORS=0
WARNINGS=0

echo -e "${BLUE}🔍 Code Quality Validation${NC}"
echo "========================="
echo ""

# ============================================================
# ARCHITECTURE CHECKS
# ============================================================

# Check A1: NO WebSocket Usage
echo "📋 Check A1: WebSocket usage (FORBIDDEN)..."
WEBSOCKET_USAGE=$(grep -r "new WebSocket\|WebSocket(" apps/ 2>/dev/null | \
  grep -v "node_modules\|dist\|coverage\|OLD_PROJECT" | wc -l | tr -d ' ')

if [ "$WEBSOCKET_USAGE" -gt 0 ]; then
  echo -e "${RED}❌ Found WebSocket usage (violates Rule A1):${NC}"
  grep -rn "new WebSocket\|WebSocket(" apps/ 2>/dev/null | \
    grep -v "node_modules\|dist\|coverage\|OLD_PROJECT"
  echo -e "${YELLOW}Use HTTP polling instead. See CODE_QUALITY_PROTOCOL.md → Rule A1${NC}"
  ERRORS=$((ERRORS + 1))
else
  echo -e "${GREEN}✅ No WebSocket usage${NC}"
fi
echo ""

# Check A2: Components calling API directly (should use services)
echo "📋 Check A2: Components calling API directly..."
DIRECT_API=$(grep -r "fetch(\|axios\." apps/web/src/modules/*/components/ 2>/dev/null | \
  grep -v "node_modules\|dist\|coverage" | wc -l | tr -d ' ')

if [ "$DIRECT_API" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found API calls in components (should use services):${NC}"
  grep -rn "fetch(\|axios\." apps/web/src/modules/*/components/ 2>/dev/null | \
    grep -v "node_modules\|dist\|coverage" | head -5
  echo -e "${YELLOW}Move API logic to services/. See CODE_QUALITY_PROTOCOL.md → Rule A2${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ Components use services for API calls${NC}"
fi
echo ""

# Check A3: Backend controllers accessing database directly
echo "📋 Check A3: Controllers accessing database directly..."
DB_IN_CONTROLLER=$(grep -r "firestore\.\|db\." apps/api/src/modules/*/\*.controller.ts 2>/dev/null | \
  grep -v "this.service\|this.repository" | wc -l | tr -d ' ')

if [ "$DB_IN_CONTROLLER" -gt 0 ]; then
  echo -e "${RED}❌ Found database access in controllers:${NC}"
  grep -rn "firestore\.\|db\." apps/api/src/modules/*/\*.controller.ts 2>/dev/null | \
    grep -v "this.service\|this.repository"
  echo -e "${YELLOW}Use repository layer. See CODE_QUALITY_PROTOCOL.md → Rule A3${NC}"
  ERRORS=$((ERRORS + 1))
else
  echo -e "${GREEN}✅ Controllers use service/repository layers${NC}"
fi
echo ""

# ============================================================
# SECURITY CHECKS
# ============================================================

# Check S1: Missing input validation
echo "📋 Check S1: Missing input validation..."
MISSING_VALIDATION=$(find apps/api/src/modules -name "*.controller.ts" -exec grep -L "Schema.parse\|z.parse" {} \; 2>/dev/null | wc -l | tr -d ' ')

if [ "$MISSING_VALIDATION" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found ${MISSING_VALIDATION} controllers without Zod validation:${NC}"
  find apps/api/src/modules -name "*.controller.ts" -exec grep -L "Schema.parse\|z.parse" {} \; 2>/dev/null | head -3
  echo -e "${YELLOW}Add Zod validation. See CODE_QUALITY_PROTOCOL.md → Rule S1${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ Controllers use input validation${NC}"
fi
echo ""

# Check S2: Unprotected API routes
echo "📋 Check S2: Unprotected API routes..."
UNPROTECTED=$(grep -r "app\.\(get\|post\|patch\|delete\)" apps/api/src/modules/*/\*.routes.ts 2>/dev/null | \
  grep -v "preHandler.*requireAuth\|preHandler.*authenticate" | wc -l | tr -d ' ')

if [ "$UNPROTECTED" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found ${UNPROTECTED} potentially unprotected routes:${NC}"
  grep -rn "app\.\(get\|post\|patch\|delete\)" apps/api/src/modules/*/\*.routes.ts 2>/dev/null | \
    grep -v "preHandler.*requireAuth\|preHandler.*authenticate" | head -3
  echo -e "${YELLOW}Add requireAuth middleware. See CODE_QUALITY_PROTOCOL.md → Rule S2${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ Routes use authentication middleware${NC}"
fi
echo ""

# Check S3: console.log in production code
echo "📋 Check S3: Debug logs in production code..."
DEBUG_LOGS=$(grep -r "console\.log" apps/ 2>/dev/null | \
  grep -v "node_modules\|dist\|coverage\|OLD_PROJECT\|archive\|\.test\.\|\.spec\." | wc -l | tr -d ' ')

if [ "$DEBUG_LOGS" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found ${DEBUG_LOGS} console.log statements:${NC}"
  grep -rn "console\.log" apps/ 2>/dev/null | \
    grep -v "node_modules\|dist\|coverage\|OLD_PROJECT\|archive\|\.test\.\|\.spec\." | head -5
  echo -e "${YELLOW}Use console.error or logger. Remove before commit.${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ No debug logs in production code${NC}"
fi
echo ""

# ============================================================
# FIREBASE CHECKS
# ============================================================

# Check F1: Client SDK used on backend
echo "📋 Check F1: Firebase client SDK on backend..."
CLIENT_SDK=$(grep -r "from 'firebase/\|from \"firebase/" apps/api/src/ 2>/dev/null | \
  grep -v "node_modules\|dist" | wc -l | tr -d ' ')

if [ "$CLIENT_SDK" -gt 0 ]; then
  echo -e "${RED}❌ Found Firebase client SDK on backend:${NC}"
  grep -rn "from 'firebase/\|from \"firebase/" apps/api/src/ 2>/dev/null | \
    grep -v "node_modules\|dist"
  echo -e "${YELLOW}Use firebase-admin. See CODE_QUALITY_PROTOCOL.md → Rule F1${NC}"
  ERRORS=$((ERRORS + 1))
else
  echo -e "${GREEN}✅ Backend uses Admin SDK${NC}"
fi
echo ""

# Check F2: Sequential Firestore writes (should use batch)
echo "📋 Check F2: Sequential Firestore writes..."
SEQUENTIAL_WRITES=$(grep -r "for.*await.*\.add(\|for.*await.*\.set(" apps/api/src/ 2>/dev/null | \
  grep -v "node_modules\|dist" | wc -l | tr -d ' ')

if [ "$SEQUENTIAL_WRITES" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found sequential Firestore writes:${NC}"
  grep -rn "for.*await.*\.add(\|for.*await.*\.set(" apps/api/src/ 2>/dev/null | \
    grep -v "node_modules\|dist"
  echo -e "${YELLOW}Use batch writes. See CODE_QUALITY_PROTOCOL.md → Rule F2${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ No sequential Firestore writes detected${NC}"
fi
echo ""

# Check F3: Offset pagination (should use cursor)
echo "📋 Check F3: Offset-based pagination..."
OFFSET_PAGINATION=$(grep -r "\.offset(" apps/api/src/ 2>/dev/null | \
  grep -v "node_modules\|dist" | wc -l | tr -d ' ')

if [ "$OFFSET_PAGINATION" -gt 0 ]; then
  echo -e "${RED}❌ Found offset-based pagination:${NC}"
  grep -rn "\.offset(" apps/api/src/ 2>/dev/null | \
    grep -v "node_modules\|dist"
  echo -e "${YELLOW}Use cursor-based pagination. See CODE_QUALITY_PROTOCOL.md → Rule F4${NC}"
  ERRORS=$((ERRORS + 1))
else
  echo -e "${GREEN}✅ No offset pagination detected${NC}"
fi
echo ""

# ============================================================
# PERFORMANCE CHECKS
# ============================================================

# Check P1: Missing computed/memoization
echo "📋 Check P1: Expensive computations in methods..."
METHODS_WITH_LOOPS=$(grep -r "const.*=.*() => {.*\.reduce(\|const.*=.*() => {.*\.map(\|const.*=.*() => {.*\.filter(" apps/web/src/ 2>/dev/null | \
  grep -v "node_modules\|dist\|coverage" | wc -l | tr -d ' ')

if [ "$METHODS_WITH_LOOPS" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found methods with array operations (consider computed):${NC}"
  grep -rn "const.*=.*() => {.*\.reduce(\|const.*=.*() => {.*\.map(\|const.*=.*() => {.*\.filter(" apps/web/src/ 2>/dev/null | \
    grep -v "node_modules\|dist\|coverage" | head -3
  echo -e "${YELLOW}Use computed() for reactive caching. See CODE_QUALITY_PROTOCOL.md → Rule P1${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ No obvious performance issues in computations${NC}"
fi
echo ""

# Check P2: Missing debounce on input
echo "📋 Check P2: Missing debounce on user input..."
INPUT_WITHOUT_DEBOUNCE=$(grep -r "@input=\|@change=" apps/web/src/ 2>/dev/null | \
  grep -v "node_modules\|dist\|coverage" | \
  xargs -I {} grep -L "debounce\|useDebounceFn" 2>/dev/null | wc -l | tr -d ' ')

if [ "$INPUT_WITHOUT_DEBOUNCE" -gt 3 ]; then
  echo -e "${YELLOW}⚠️  Found ${INPUT_WITHOUT_DEBOUNCE} input handlers without debounce:${NC}"
  echo -e "${YELLOW}Consider debouncing search/filter inputs. See CODE_QUALITY_PROTOCOL.md → Rule P2${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ Input handlers appear debounced${NC}"
fi
echo ""

# Check P3: Eager imports (should be lazy)
echo "📋 Check P3: Eager route imports..."
EAGER_IMPORTS=$(grep -r "import.*from.*pages" apps/web/src/router/ 2>/dev/null | \
  grep -v "() => import\|defineAsyncComponent" | wc -l | tr -d ' ')

if [ "$EAGER_IMPORTS" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found eager imports in router:${NC}"
  grep -rn "import.*from.*pages" apps/web/src/router/ 2>/dev/null | \
    grep -v "() => import\|defineAsyncComponent"
  echo -e "${YELLOW}Use lazy loading. See CODE_QUALITY_PROTOCOL.md → Rule P3${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ Routes use lazy loading${NC}"
fi
echo ""

# ============================================================
# CRDT SYNC CHECKS
# ============================================================

# Check C1: Direct Y.Doc mutations in components
echo "📋 Check C1: Direct Y.Doc mutations in components..."
YDOC_IN_COMPONENTS=$(grep -r "ydoc\.\|Y\.Doc\|ymap\.set\|yarray\.push" apps/web/src/modules/*/components/ 2>/dev/null | \
  grep -v "node_modules\|dist\|coverage" | wc -l | tr -d ' ')

if [ "$YDOC_IN_COMPONENTS" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found Y.Doc mutations in components:${NC}"
  grep -rn "ydoc\.\|Y\.Doc\|ymap\.set\|yarray\.push" apps/web/src/modules/*/components/ 2>/dev/null | \
    grep -v "node_modules\|dist\|coverage" | head -3
  echo -e "${YELLOW}Use sync service. See CODE_QUALITY_PROTOCOL.md → Rule C1${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ Components use sync service${NC}"
fi
echo ""

# ============================================================
# OFFLINE CHECKS
# ============================================================

# Check O1: Network errors not handled
echo "📋 Check O1: Missing offline error handling..."
UNHANDLED_NETWORK=$(grep -r "await.*api\.\|await.*fetch(" apps/web/src/modules/*/services/ 2>/dev/null | \
  grep -v "node_modules\|dist\|coverage" | \
  xargs -I {} grep -L "catch\|try" 2>/dev/null | wc -l | tr -d ' ')

if [ "$UNHANDLED_NETWORK" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found ${UNHANDLED_NETWORK} services without error handling:${NC}"
  echo -e "${YELLOW}Add try/catch + offline queue. See CODE_QUALITY_PROTOCOL.md → Rule O2${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ Services handle network errors${NC}"
fi
echo ""

# ============================================================
# API DESIGN CHECKS
# ============================================================

# Check D1: Non-RESTful endpoint names
echo "📋 Check D1: Non-RESTful endpoint names..."
NON_RESTFUL=$(grep -r "app\.\(get\|post\|patch\|delete\).*\/api\/\(get\|create\|update\|delete\)" apps/api/src/ 2>/dev/null | \
  grep -v "node_modules\|dist" | wc -l | tr -d ' ')

if [ "$NON_RESTFUL" -gt 0 ]; then
  echo -e "${YELLOW}⚠️  Found non-RESTful endpoint names:${NC}"
  grep -rn "app\.\(get\|post\|patch\|delete\).*\/api\/\(get\|create\|update\|delete\)" apps/api/src/ 2>/dev/null | \
    grep -v "node_modules\|dist"
  echo -e "${YELLOW}Use RESTful naming. See CODE_QUALITY_PROTOCOL.md → Rule D1${NC}"
  WARNINGS=$((WARNINGS + 1))
else
  echo -e "${GREEN}✅ Endpoints use RESTful naming${NC}"
fi
echo ""

# Check D2: Inconsistent status codes
echo "📋 Check D2: Wrong HTTP status codes..."
WRONG_STATUS=$(grep -r "reply\.status(200)\.send.*error\|reply\.status(500).*not found" apps/api/src/ 2>/dev/null | \
  grep -v "node_modules\|dist" | wc -l | tr -d ' ')

if [ "$WRONG_STATUS" -gt 0 ]; then
  echo -e "${RED}❌ Found wrong HTTP status codes:${NC}"
  grep -rn "reply\.status(200)\.send.*error\|reply\.status(500).*not found" apps/api/src/ 2>/dev/null | \
    grep -v "node_modules\|dist"
  echo -e "${YELLOW}Use correct codes. See CODE_QUALITY_PROTOCOL.md → Rule D3${NC}"
  ERRORS=$((ERRORS + 1))
else
  echo -e "${GREEN}✅ HTTP status codes appear correct${NC}"
fi
echo ""

# ============================================================
# ERROR HANDLING CHECKS
# ============================================================

# Check E1: Silent error swallowing
echo "📋 Check E1: Silent error handling..."
EMPTY_CATCH=$(grep -r "catch.*{.*}" apps/ 2>/dev/null | \
  grep -v "node_modules\|dist\|coverage\|OLD_PROJECT" | wc -l | tr -d ' ')

if [ "$EMPTY_CATCH" -gt 0 ]; then
  echo -e "${RED}❌ Found empty catch blocks:${NC}"
  grep -rn "catch.*{.*}" apps/ 2>/dev/null | \
    grep -v "node_modules\|dist\|coverage\|OLD_PROJECT" | head -5
  echo -e "${YELLOW}Add error logging/handling. See CODE_QUALITY_PROTOCOL.md → Rule E1${NC}"
  ERRORS=$((ERRORS + 1))
else
  echo -e "${GREEN}✅ No empty catch blocks${NC}"
fi
echo ""

# ============================================================
# SUMMARY
# ============================================================

echo "========================="
if [ "$ERRORS" -eq 0 ] && [ "$WARNINGS" -eq 0 ]; then
  echo -e "${GREEN}✅ All code quality checks passed!${NC}"
  echo ""
  echo "Safe to commit. Code follows best practices."
  exit 0
elif [ "$ERRORS" -eq 0 ]; then
  echo -e "${YELLOW}⚠️  Found ${WARNINGS} warnings${NC}"
  echo ""
  echo "Consider fixing warnings before commit."
  echo "See .github/instructions/CODE_QUALITY_PROTOCOL.md"
  exit 0
else
  echo -e "${RED}❌ Found ${ERRORS} errors and ${WARNINGS} warnings${NC}"
  echo ""
  echo "Please fix the errors above before committing."
  echo "See .github/instructions/CODE_QUALITY_PROTOCOL.md for guidance."
  echo ""
  echo "To see specific rules:"
  echo "  grep 'Rule [A-Z][0-9]' .github/instructions/CODE_QUALITY_PROTOCOL.md"
  exit 1
fi
