#!/bin/bash

# =============================================================================
# Script: validate-ddl-organization.sh
# Propósito: Validar que todos los objetos DDL estén en los schemas correctos
# Uso: ./validate-ddl-organization.sh
# Salida: Reporte de validación en formato YAML
# Creado: 2025-11-09
# =============================================================================

set -e

BASE_DIR="/home/isem/workspace/workspace-gamilit/gamilit/projects/gamilit/apps/database/ddl/schemas"
OUTPUT_FILE="/tmp/ddl-validation-$(date +%Y%m%d-%H%M%S).yaml"

echo "=== VALIDACIÓN DE ORGANIZACIÓN DDL ==="
echo "Fecha: $(date)"
echo "Base directory: $BASE_DIR"
echo ""

# Colores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Contadores globales
TOTAL_ISSUES=0
CRITICAL_ISSUES=0
MINOR_ISSUES=0

# =============================================================================
# 1. VALIDAR PUBLIC SCHEMA
# =============================================================================

echo "1. Validando Public Schema..."

PUBLIC_TABLES=$(find "$BASE_DIR/public/tables" -name "*.sql" 2>/dev/null | wc -l)
PUBLIC_FUNCTIONS=$(find "$BASE_DIR/public/functions" -name "*.sql" 2>/dev/null | wc -l)
PUBLIC_ENUMS=$(find "$BASE_DIR/public/enums" -name "*.sql" ! -path "*/_deprecated/*" 2>/dev/null | wc -l)
PUBLIC_VIEWS=$(find "$BASE_DIR/public/views" -name "*.sql" 2>/dev/null | wc -l)

if [ "$PUBLIC_TABLES" -gt 0 ]; then
    echo -e "${RED}✗ ERROR: Tablas encontradas en public schema${NC}"
    CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1))
else
    echo -e "${GREEN}✓ No hay tablas en public schema${NC}"
fi

if [ "$PUBLIC_FUNCTIONS" -gt 0 ]; then
    echo -e "${RED}✗ ERROR: Funciones encontradas en public schema${NC}"
    CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1))
else
    echo -e "${GREEN}✓ No hay funciones en public schema${NC}"
fi

if [ "$PUBLIC_ENUMS" -gt 0 ]; then
    echo -e "${RED}✗ ERROR: ENUMs activos encontrados en public schema${NC}"
    CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1))
else
    echo -e "${GREEN}✓ No hay ENUMs activos en public schema${NC}"
fi

if [ "$PUBLIC_VIEWS" -le 5 ]; then
    echo -e "${GREEN}✓ Public schema tiene $PUBLIC_VIEWS views (aceptable)${NC}"
else
    echo -e "${YELLOW}⚠ Public schema tiene $PUBLIC_VIEWS views (considerar mover a schema dedicado)${NC}"
    MINOR_ISSUES=$((MINOR_ISSUES + 1))
fi

echo ""

# =============================================================================
# 2. VALIDAR INDEXES CON SCHEMA CALIFICADO
# =============================================================================

echo "2. Validando Indexes con schema calificado..."

TOTAL_INDEXES=$(find "$BASE_DIR" -path "*/indexes/*.sql" -type f 2>/dev/null | wc -l)

# Buscar indexes sin schema.tabla en ON clause
UNQUALIFIED_INDEXES=0

while IFS= read -r file; do
    # Extraer líneas CREATE INDEX y verificar si la siguiente línea tiene schema.tabla
    if grep -q "CREATE INDEX" "$file"; then
        # Obtener línea completa del CREATE INDEX + ON
        INDEX_STATEMENT=$(grep -A1 "CREATE INDEX" "$file" | tr '\n' ' ')

        # Verificar si contiene ON schema.tabla
        if ! echo "$INDEX_STATEMENT" | grep -q "ON [a-z_]*\.[a-z_]*"; then
            echo -e "${YELLOW}⚠ Index sin schema calificado: $file${NC}"
            UNQUALIFIED_INDEXES=$((UNQUALIFIED_INDEXES + 1))
        fi
    fi
done < <(find "$BASE_DIR" -path "*/indexes/*.sql" -type f 2>/dev/null)

if [ "$UNQUALIFIED_INDEXES" -eq 0 ]; then
    echo -e "${GREEN}✓ Todos los $TOTAL_INDEXES indexes tienen schema calificado${NC}"
else
    echo -e "${YELLOW}⚠ $UNQUALIFIED_INDEXES de $TOTAL_INDEXES indexes sin schema calificado${NC}"
    MINOR_ISSUES=$((MINOR_ISSUES + UNQUALIFIED_INDEXES))
fi

echo ""

# =============================================================================
# 3. VALIDAR DISTRIBUCIÓN DE FUNCIONES
# =============================================================================

echo "3. Validando distribución de funciones..."

TOTAL_FUNCTIONS=$(find "$BASE_DIR" -path "*/functions/*.sql" ! -path "*/_deprecated/*" -type f 2>/dev/null | wc -l)

# Verificar que funciones utilitarias estén en gamilit
GAMILIT_FUNCTIONS=$(find "$BASE_DIR/gamilit/functions" -name "*.sql" 2>/dev/null | wc -l)

echo -e "${GREEN}✓ Total funciones: $TOTAL_FUNCTIONS${NC}"
echo -e "${GREEN}✓ Funciones en gamilit (utilitarias): $GAMILIT_FUNCTIONS${NC}"

# Listar funciones por schema
for schema in audit_logging gamification_system educational_content progress_tracking auth_management; do
    count=$(find "$BASE_DIR/$schema/functions" -name "*.sql" ! -path "*/_deprecated/*" 2>/dev/null | wc -l)
    if [ "$count" -gt 0 ]; then
        echo "  - $schema: $count funciones"
    fi
done

echo ""

# =============================================================================
# 4. VALIDAR RLS EN TABLAS CRÍTICAS
# =============================================================================

echo "4. Validando RLS en tablas críticas..."

CRITICAL_TABLES=("user_suspensions" "flagged_content" "user_activity_logs")
RLS_MISSING=0

for table in "${CRITICAL_TABLES[@]}"; do
    # Buscar si hay RLS policies para esta tabla
    if grep -rq "$table" "$BASE_DIR"/*/rls-policies/*.sql 2>/dev/null; then
        echo -e "${GREEN}✓ Tabla crítica '$table' tiene RLS policies${NC}"
    else
        echo -e "${RED}✗ ERROR: Tabla crítica '$table' NO tiene RLS policies${NC}"
        CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1))
        RLS_MISSING=$((RLS_MISSING + 1))
    fi
done

echo ""

# =============================================================================
# 5. VALIDAR TRIGGERS HUÉRFANOS
# =============================================================================

echo "5. Validando triggers huérfanos..."

TOTAL_TRIGGERS=$(find "$BASE_DIR" -path "*/triggers/*.sql" -type f 2>/dev/null | wc -l)

echo -e "${GREEN}✓ Total triggers: $TOTAL_TRIGGERS${NC}"
echo "  (Validación manual requerida para verificar que triggers tengan tablas correspondientes)"

echo ""

# =============================================================================
# 6. GENERAR REPORTE YAML
# =============================================================================

cat > "$OUTPUT_FILE" << EOF
validacion_ddl_organization:
  fecha: "$(date -I)"
  hora: "$(date +%H:%M:%S)"

  resumen:
    estado_general: "$([ $CRITICAL_ISSUES -eq 0 ] && echo "PASS" || echo "FAIL")"
    problemas_criticos: $CRITICAL_ISSUES
    problemas_menores: $MINOR_ISSUES
    total_problemas: $((CRITICAL_ISSUES + MINOR_ISSUES))

  public_schema:
    tablas: $PUBLIC_TABLES
    funciones: $PUBLIC_FUNCTIONS
    enums: $PUBLIC_ENUMS
    views: $PUBLIC_VIEWS
    estado: "$([ $PUBLIC_TABLES -eq 0 ] && [ $PUBLIC_FUNCTIONS -eq 0 ] && [ $PUBLIC_ENUMS -eq 0 ] && echo "LIMPIO" || echo "CONTAMINADO")"

  indexes:
    total: $TOTAL_INDEXES
    sin_schema_calificado: $UNQUALIFIED_INDEXES
    porcentaje_correctos: $(awk "BEGIN {printf \"%.1f\", ($TOTAL_INDEXES - $UNQUALIFIED_INDEXES) * 100.0 / $TOTAL_INDEXES}")%

  funciones:
    total: $TOTAL_FUNCTIONS
    en_gamilit: $GAMILIT_FUNCTIONS

  rls_policies:
    tablas_criticas_validadas: ${#CRITICAL_TABLES[@]}
    tablas_sin_rls: $RLS_MISSING
    cobertura: "$([ $RLS_MISSING -eq 0 ] && echo "100%" || echo "Incompleta")"

  triggers:
    total: $TOTAL_TRIGGERS

  recomendacion: "$([ $CRITICAL_ISSUES -eq 0 ] && echo "APROBAR" || echo "RECHAZAR - Corregir problemas críticos")"
EOF

echo "=== RESUMEN ==="
echo ""
echo "Problemas críticos: $CRITICAL_ISSUES"
echo "Problemas menores:  $MINOR_ISSUES"
echo "Total problemas:    $((CRITICAL_ISSUES + MINOR_ISSUES))"
echo ""

if [ $CRITICAL_ISSUES -eq 0 ]; then
    echo -e "${GREEN}✓ VALIDACIÓN EXITOSA - No hay problemas críticos${NC}"
    EXIT_CODE=0
else
    echo -e "${RED}✗ VALIDACIÓN FALLIDA - $CRITICAL_ISSUES problema(s) crítico(s)${NC}"
    EXIT_CODE=1
fi

echo ""
echo "Reporte generado: $OUTPUT_FILE"
echo ""

# Mostrar contenido del reporte
cat "$OUTPUT_FILE"

exit $EXIT_CODE
