# Build script for GestoreTrimestrale
param(
    [string]$LocalWorkspace = "C:\TFS Fideuram\TP_SEI_Project\root",
    [switch]$SkipTests = $true,
    [switch]$RunApp
)

# Start logging to file
$logFile = Join-Path $PSScriptRoot "arm_build.log"
Start-Transcript -Path $logFile -Force

# Function to handle errors
function Write-ErrorAndExit {
    param([string]$ErrorMessage)
    Write-Error $ErrorMessage
    Stop-Transcript
    exit 1
}

# Validate paths
$AppConfigTest = Join-Path $LocalWorkspace "ContrattoSEI\GestoreTrimestrale.Test\app.config"
$AppConfigApp = Join-Path $LocalWorkspace "ContrattoSEI\GestoreTrimestrale\app.config"
$Solution = Join-Path $LocalWorkspace "ContrattoSEI\GestoreTrimestrale\GestoreTrimestrale.sln"
$TestDll = Join-Path $LocalWorkspace "ContrattoSEI\GestoreTrimestrale.Test\bin\Debug\GestoreTrimestrale.Test.dll"
$ProjectExe = Join-Path $LocalWorkspace "ContrattoSEI\GestoreTrimestrale\bin\Debug\GestoreTrimestrale.exe"

# Check .NET Framework versions and SDK
function Test-NetFramework {
    param([string]$Version)
    
    # Check for .NET Framework 4.x installations
    $netKey = "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
    if (-not (Test-Path $netKey)) {
        Write-Warning ".NET Framework 4.x runtime not found. Please install from: https://dotnet.microsoft.com/download/dotnet-framework"
        return $false
    }
    
    # Check for Developer Pack/SDK
    $sdkPaths = @(
        "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools",
        "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools",
        "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.1 Tools",
        "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7 Tools",
        "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools",
        "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools",
        "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools",
        "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.5.1 Tools",
        "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.5 Tools"
    )
    
    $sdkFound = $false
    foreach ($path in $sdkPaths) {
        if (Test-Path $path) {
            Write-Host "Found .NET Framework SDK at: $path" -ForegroundColor Green
            $sdkFound = $true
            break
        }
    }
    
    if (-not $sdkFound) {
        Write-Warning ".NET Framework Developer Pack/SDK not found. Please install from: https://dotnet.microsoft.com/download/visual-studio-sdks"
        return $false
    }
    
    return $true
}

$requiredVersions = @("4.0", "4.5")
foreach ($version in $requiredVersions) {
    if (-not (Test-NetFramework $version)) {
        Write-ErrorAndExit ".NET Framework $version or later is required but not installed. Please install from: https://dotnet.microsoft.com/download/dotnet-framework"
    }
}

# Validate Visual Studio 2022 installation
$vsPath = 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise'
if (-not (Test-Path $vsPath)) {
    $vsPath = 'C:\Program Files\Microsoft Visual Studio\2022\Professional'
    if (-not (Test-Path $vsPath)) {
        $vsPath = 'C:\Program Files\Microsoft Visual Studio\2022\Community'
        if (-not (Test-Path $vsPath)) {
            Write-ErrorAndExit "Visual Studio 2022 not found in any standard installation paths"
        }
    }
}

Write-Host "Setting up Visual Studio environment..." -ForegroundColor Yellow
try {
    # Find development tools
    $devEnvPath = Join-Path $vsPath 'Common7\IDE\devenv.com'
    $msBuildPath = Join-Path $vsPath 'MSBuild\Current\Bin\MSBuild.exe'
    
    if (-not (Test-Path $msBuildPath)) {
        $msBuildPath = Join-Path $vsPath 'MSBuild\Current\Bin\amd64\MSBuild.exe'
        if (-not (Test-Path $msBuildPath)) {
            Write-ErrorAndExit "MSBuild not found in expected paths"
        }
    }
    
    # Clean solution first
    if (Test-Path $devEnvPath) {
        Write-Host "Cleaning solution..." -ForegroundColor Yellow
        & $devEnvPath $Solution /Clean
    }
    
    # Set up environment
    $vcvarsPath = Join-Path $vsPath 'VC\Auxiliary\Build\vcvars64.bat'
    $tempFile = [System.IO.Path]::GetTempFileName()
    cmd /c "\"$vcvarsPath\" && set > \"$tempFile\""
    Get-Content $tempFile | ForEach-Object {
        if ($_ -match "=") {
            $v = $_.split("=")
            Set-Item -Force -Path "ENV:\$($v[0])" -value "$($v[1])"
        }
    }
    Remove-Item $tempFile -ErrorAction SilentlyContinue
} catch {
    Write-ErrorAndExit "Failed to set up Visual Studio environment: $_"
}

# Check for Azure DevOps/TFS module
$tfModule = Get-Module -Name "Microsoft.TeamFoundation.PowerShell" -ListAvailable -ErrorAction SilentlyContinue
if ($tfModule) {
    try {
        Import-Module "Microsoft.TeamFoundation.PowerShell" -ErrorAction Stop
        # Update TFS workspace
        Write-Host "Updating TFS workspace..." -ForegroundColor Yellow
        Update-TfsWorkspace -Force -Recurse $LocalWorkspace
    } catch {
        Write-Warning "TFS operations will be skipped: $_"
    }
} else {
    Write-Warning "TFS/Azure DevOps PowerShell module not found. TFS operations will be skipped."
}

# Update configuration files
Write-Host "Updating configuration files..." -ForegroundColor Yellow
try {
    if (Test-Path $AppConfigTest) {
        (Get-Content $AppConfigTest).replace('c:\', 'c:\') | Set-Content $AppConfigTest
    }
    if (Test-Path $AppConfigApp) {
        (Get-Content $AppConfigApp).replace('c:\', 'c:\') | Set-Content $AppConfigApp
    }
} catch {
    Write-ErrorAndExit "Failed to update configuration files: $_"
}

# Build solution
Write-Host "Building solution..." -ForegroundColor Yellow

# Download latest NuGet if not found
Write-Host "Setting up NuGet..." -ForegroundColor Yellow
$nugetPath = "$env:LOCALAPPDATA\NuGet\nuget.exe"
if (-not (Test-Path $nugetPath)) {
    $nugetFolder = Split-Path $nugetPath -Parent
    if (-not (Test-Path $nugetFolder)) {
        New-Item -ItemType Directory -Path $nugetFolder | Out-Null
    }
    Invoke-WebRequest -Uri "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -OutFile $nugetPath
}

# Restore and Build
Write-Host "Restoring NuGet packages..." -ForegroundColor Yellow
& $nugetPath restore $Solution

Write-Host "Building solution..." -ForegroundColor Yellow

# Build with original framework versions
$buildOutput = & $msBuildPath $Solution /p:Configuration=Debug /nologo /p:Platform="Any CPU" /t:Clean,Rebuild /m /verbosity:detailed 2>&1
$buildOutput | ForEach-Object { Write-Host $_ }
if ($LASTEXITCODE -ne 0) {
    Write-ErrorAndExit "Build failed with exit code: $LASTEXITCODE"
}

# Run tests if not skipped
if (-not $SkipTests) {
    Write-Host "Running tests..." -ForegroundColor Yellow
    $tests = @(
        "FlushFilesWaitingForZIP",
        "SetUpZipCases_DoNotUse",
        "ProcessCanComplete",
        "ZipIntegrity",
        "NumberOfPackedPDFIsOK"
    )

    foreach ($test in $tests) {
        Write-Host "Running test: $test" -ForegroundColor Cyan
        vstest.console.exe $TestDll /Tests:$test
        if ($LASTEXITCODE -ne 0) {
            Write-ErrorAndExit "Test '$test' failed with exit code: $LASTEXITCODE"
        }
    }
}

# Run application if requested
if ($RunApp) {
    Write-Host "Launching application..." -ForegroundColor Yellow
    try {
        Start-Process -FilePath $ProjectExe -Wait
    } catch {
        Write-ErrorAndExit "Failed to launch application: $_"
    }
}

# Stop logging
Stop-Transcript

Write-Host "Build process completed successfully!" -ForegroundColor Green