# Importa configurazione
. "$PSScriptRoot\conf.ps1"

# Imposta il percorso di output nella cartella transito
$BaseOutputPath = Join-Path $env:workdir "transito"
$StoredOutputPath = Join-Path $BaseOutputPath "procedure"
$FunctionOutputPath = Join-Path $BaseOutputPath "funzioni"
$ViewOutputPath = Join-Path $BaseOutputPath "viste"

# Verifica che le directory di output esistano, altrimenti le crea
@($StoredOutputPath, $FunctionOutputPath, $ViewOutputPath) | ForEach-Object {
    if (-not (Test-Path -Path $_)) {
        New-Item -ItemType Directory -Path $_ | Out-Null
    }
}

try {
    # Carica l'assembly System.Data
    Add-Type -AssemblyName System.Data

    # Query per estrarre stored procedures, funzioni e view
    $query = @"
    SELECT 
        s.name as SchemaName,
        o.name as ObjectName,
        CAST(m.definition as NVARCHAR(MAX)) as ObjectDefinition,
        CASE 
            WHEN o.type = 'P' THEN 'StoredProcedure'
            WHEN o.type IN ('FN', 'IF', 'TF') THEN 'Function'
            WHEN o.type = 'V' THEN 'View'
        END as ObjectType
    FROM sys.sql_modules m
    INNER JOIN sys.objects o ON m.object_id = o.object_id
    INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
    WHERE o.type IN ('P', 'FN', 'IF', 'TF', 'V')
"@

    # Crea la connessione e esegui la query
    $connectionString = "Server=$($env:dbHostInput);Database=$($env:dbNameInput);User Id=$($env:dbUserInput);Password=$($env:dbPasswordInput);TrustServerCertificate=True"
    $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
    $command = New-Object System.Data.SqlClient.SqlCommand($query, $connection)
    $adapter = New-Object System.Data.SqlClient.SqlDataAdapter($command)
    $dataset = New-Object System.Data.DataSet
    $adapter.Fill($dataset) | Out-Null
    $sqlObjects = $dataset.Tables[0]

    # Funzione per formattare il nome del file
    function Format-FileName {
        param([string]$name)
        # Sostituisce caratteri non validi con underscore
        $invalidChars = [IO.Path]::GetInvalidFileNameChars()
        $invalidChars += '[', ']', ' ', '(', ')', '{', '}', '´', '`', '''', '"'
        $result = $name
        foreach ($char in $invalidChars) {
            $result = $result.Replace($char, '_')
        }
        return $result
    }

    # Per ogni oggetto trovato
    foreach ($obj in $sqlObjects) {
        $schemaName = Format-FileName $obj.SchemaName
        $objName = Format-FileName $obj.ObjectName
        $definition = $obj.ObjectDefinition
        
        # Determina il percorso di output basato sul tipo di oggetto
        $outputDir = switch ($obj.ObjectType) {
            'StoredProcedure' { $StoredOutputPath }
            'Function' { $FunctionOutputPath }
            'View' { $ViewOutputPath }
        }
        
        # Crea il nome del file
        $fileName = Join-Path $outputDir "${schemaName}_${objName}.sql"

        # Formatta il contenuto
        # -- Schema: $schemaName
        # -- Stored Procedure: $procName
        
        $content = @"
$($definition.Trim())
"@

        # Rimuovi righe vuote multiple
        $lines = $content -split "`r`n" | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
        $content = $lines -join "`r`n"

        # Scrivi il contenuto nel file con codifica UTF8 con BOM
        $utf8WithBom = New-Object System.Text.UTF8Encoding($true)
        [System.IO.File]::WriteAllText($fileName, $content, $utf8WithBom)

        Write-Host "Creato file per $($obj.ObjectType): $schemaName.$objName"
    }

    Write-Host "`nEstrazione completata con successo!"
} catch {
    Write-Error "Errore durante l'estrazione degli oggetti del database: $_"
    exit 1
}
