# Script d'audit des migrations Flyway vs Entités JPA
# Auteur: Lions Dev
# Date: 2026-03-13

$ErrorActionPreference = "Stop"
$projectRoot = $PSScriptRoot

Write-Host "`n╔══════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
Write-Host "║   Audit Migrations Flyway vs Entités JPA - UnionFlow   ║" -ForegroundColor Cyan
Write-Host "╚══════════════════════════════════════════════════════════╝`n" -ForegroundColor Cyan

# 1. Extraire toutes les entités et leurs noms de tables
Write-Host "[1/4] Extraction des entités JPA..." -ForegroundColor Yellow

$entityFiles = Get-ChildItem -Path "$projectRoot\src\main\java\dev\lions\unionflow\server\entity" -Filter "*.java" -Recurse | Where-Object { $_.Name -ne "package-info.java" }
$entities = @{}

foreach ($file in $entityFiles) {
    $content = Get-Content $file.FullName -Raw

    # Extraire le nom de la classe
    if ($content -match 'public\s+class\s+(\w+)') {
        $className = $Matches[1]

        # Extraire le nom de la table
        $tableName = $null
        if ($content -match '@Table\s*\(\s*name\s*=\s*"([^"]+)"') {
            $tableName = $Matches[1]
        } else {
            # Si pas de @Table explicite, utiliser le nom de la classe en snake_case
            $tableName = ($className -creplace '([A-Z])', '_$1').ToLower().TrimStart('_')
        }

        $entities[$className] = @{
            TableName = $tableName
            FilePath = $file.FullName
        }
    }
}

Write-Host "  → $($entities.Count) entités trouvées" -ForegroundColor Green

# 2. Lister toutes les migrations
Write-Host "`n[2/4] Analyse des migrations Flyway..." -ForegroundColor Yellow

$migrations = Get-ChildItem -Path "$projectRoot\src\main\resources\db\migration" -Filter "V*.sql" | Sort-Object Name
$allTables = @{}

foreach ($migration in $migrations) {
    Write-Host "  → $($migration.Name)" -ForegroundColor Gray
    $content = Get-Content $migration.FullName -Raw

    # Extraire toutes les CREATE TABLE
    $matches = [regex]::Matches($content, 'CREATE\s+TABLE\s+(IF\s+NOT\s+EXISTS\s+)?([a-z_]+)', [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)

    foreach ($match in $matches) {
        $tableName = $match.Groups[2].Value
        if (-not $allTables.ContainsKey($tableName)) {
            $allTables[$tableName] = @()
        }
        $allTables[$tableName] += $migration.Name
    }
}

Write-Host "  → $($allTables.Keys.Count) tables uniques trouvées dans les migrations" -ForegroundColor Green

# 3. Comparaison
Write-Host "`n[3/4] Comparaison Entités <-> Migrations..." -ForegroundColor Yellow

$missingInMigrations = @()
$missingInEntities = @()
$ok = @()

foreach ($entity in $entities.Keys) {
    $tableName = $entities[$entity].TableName

    if ($allTables.ContainsKey($tableName)) {
        $ok += @{
            Entity = $entity
            Table = $tableName
            Migrations = $allTables[$tableName] -join ", "
        }
    } else {
        $missingInMigrations += @{
            Entity = $entity
            Table = $tableName
        }
    }
}

foreach ($table in $allTables.Keys) {
    $found = $false
    foreach ($entity in $entities.Keys) {
        if ($entities[$entity].TableName -eq $table) {
            $found = $true
            break
        }
    }

    if (-not $found) {
        $missingInEntities += @{
            Table = $table
            Migrations = $allTables[$table] -join ", "
        }
    }
}

# 4. Rapport
Write-Host "`n[4/4] Génération du rapport..." -ForegroundColor Yellow

$report = @"
# Rapport d'Audit - Migrations Flyway vs Entités JPA
Date: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")

## Résumé
- **Entités JPA**: $($entities.Count)
- **Tables dans migrations**: $($allTables.Keys.Count)
- **OK (match)**: $($ok.Count)
- **⚠️ Entités sans table**: $($missingInMigrations.Count)
- **⚠️ Tables sans entité**: $($missingInEntities.Count)

---

## ✅ Entités avec table correspondante ($($ok.Count))

| Entité | Table | Migration(s) |
|--------|-------|--------------|
"@

foreach ($item in $ok | Sort-Object { $_.Entity }) {
    $report += "`n| $($item.Entity) | $($item.Table) | $($item.Migrations) |"
}

if ($missingInMigrations.Count -gt 0) {
    $report += @"

---

## ⚠️ Entités SANS table dans les migrations ($($missingInMigrations.Count))

**ACTION REQUISE**: Ces entités existent dans le code mais n'ont pas de table dans les migrations!

| Entité | Table attendue |
|--------|----------------|
"@

    foreach ($item in $missingInMigrations | Sort-Object { $_.Table }) {
        $report += "`n| $($item.Entity) | ``$($item.Table)`` |"
    }
}

if ($missingInEntities.Count -gt 0) {
    $report += @"

---

## ⚠️ Tables SANS entité correspondante ($($missingInEntities.Count))

**ACTION REQUISE**: Ces tables existent dans les migrations mais n'ont pas d'entité Java!
**Recommandation**: Supprimer ces tables des migrations ou créer les entités manquantes.

| Table | Migration(s) |
|-------|--------------|
"@

    foreach ($item in $missingInEntities | Sort-Object { $_.Table }) {
        $report += "`n| ``$($item.Table)`` | $($item.Migrations) |"
    }
}

$report += @"


---

## Duplications de CREATE TABLE

"@

$duplicates = $allTables.GetEnumerator() | Where-Object { $_.Value.Count -gt 1 }
if ($duplicates.Count -gt 0) {
    $report += "**ACTION REQUISE**: Ces tables sont créées dans plusieurs migrations!`n`n"
    $report += "| Table | Migrations |`n"
    $report += "|-------|------------|`n"

    foreach ($dup in $duplicates | Sort-Object { $_.Key }) {
        $report += "| ``$($dup.Key)`` | $($dup.Value -join ", ") |`n"
    }
} else {
    $report += "✅ Aucune duplication détectée.`n"
}

$report += @"

---

## Recommandations

1. **Supprimer les tables obsolètes**: Tables sans entité doivent être supprimées des migrations
2. **Créer les tables manquantes**: Ajouter les CREATE TABLE pour les entités sans table
3. **Éliminer les duplications**: Garder seulement une version de chaque CREATE TABLE (de préférence avec IF NOT EXISTS)
4. **Nettoyer V1**: Supprimer toutes les sections redondantes (CREATE/DROP/CREATE)
5. **Vérifier les FK**: S'assurer que toutes les clés étrangères référencent des tables existantes

---

*Généré par audit-migrations.ps1 - Lions Dev*

"@

# Sauvegarder le rapport
$reportPath = "$projectRoot\AUDIT_MIGRATIONS.md"
$report | Out-File -FilePath $reportPath -Encoding UTF8

Write-Host "`n✅ Rapport sauvegardé: $reportPath" -ForegroundColor Green

# Afficher le résumé
Write-Host "`n╔══════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
Write-Host "║                     RÉSUMÉ                               ║" -ForegroundColor Cyan
Write-Host "╚══════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
Write-Host "  Entités JPA: $($entities.Count)" -ForegroundColor White
Write-Host "  Tables migrations: $($allTables.Keys.Count)" -ForegroundColor White
Write-Host "  ✅ OK: $($ok.Count)" -ForegroundColor Green

if ($missingInMigrations.Count -gt 0) {
    Write-Host "  ⚠️  Entités sans table: $($missingInMigrations.Count)" -ForegroundColor Yellow
}

if ($missingInEntities.Count -gt 0) {
    Write-Host "  ⚠️  Tables sans entité: $($missingInEntities.Count)" -ForegroundColor Yellow
}

if ($duplicates.Count -gt 0) {
    Write-Host "  ⚠️  Duplications: $($duplicates.Count)" -ForegroundColor Red
}

Write-Host "`nOuvrir le rapport complet? (Y/N)" -ForegroundColor Cyan
$answer = Read-Host
if ($answer -eq "Y" -or $answer -eq "y") {
    Start-Process $reportPath
}
