Demo-ADOOutput.ps1

<#
.SYNOPSIS
Quick demo of Azure DevOps AI Code Review simulation
 
.DESCRIPTION
This script creates mock violations and shows exactly how they would appear in Azure DevOps:
- Azure DevOps logging format (##vso commands)
- Color-coded output (warnings/errors)
- Summary statistics
- Build result status
 
Run this anywhere to see the ADO formatting without needing actual code violations.
 
.EXAMPLE
.\Demo-ADOOutput.ps1
 
.NOTES
Author: waldo
Version: 1.0.0
#>


# Pipeline simulation colors
$script:ADOColors = @{
    Section = "Cyan"
    Success = "Green"
    Warning = "Yellow"
    Error = "Red"
    Info = "White"
    Debug = "Gray"
}

function Write-ADOSection {
    param([string]$Message)
    Write-Host ""
    Write-Host "##[section]$Message" -ForegroundColor $script:ADOColors.Section
}

function Write-ADOCommand {
    param([string]$Message)
    Write-Host "##[command]$Message" -ForegroundColor $script:ADOColors.Debug
}

function Write-ADOWarning {
    param([string]$Message)
    Write-Host "##vso[task.logissue type=warning]$Message" -ForegroundColor $script:ADOColors.Warning
}

function Write-ADOError {
    param([string]$Message)
    Write-Host "##vso[task.logissue type=error]$Message" -ForegroundColor $script:ADOColors.Error
}

function Write-ADOSuccess {
    param([string]$Message)
    Write-Host "$Message" -ForegroundColor $script:ADOColors.Success
}

function Write-ADOInfo {
    param([string]$Message)
    Write-Host "$Message" -ForegroundColor $script:ADOColors.Info
}

# Banner
Clear-Host
Write-Host "╔════════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
Write-Host "║ ║" -ForegroundColor Cyan
Write-Host "║ Azure DevOps - AI Code Review Demo Output ║" -ForegroundColor Cyan
Write-Host "║ ║" -ForegroundColor Cyan
Write-Host "╚════════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
Write-Host ""

# Simulate pipeline start
$buildId = Get-Random -Minimum 10000 -Maximum 99999
$startTime = Get-Date
Write-ADOInfo "Build: #$buildId"
Write-ADOInfo "Started: $($startTime.ToString('yyyy-MM-dd HH:mm:ss'))"
Write-ADOInfo "Agent: Demo ($(hostname))"
Write-Host ""

# Mock changed files
$changedFiles = @(
    "src/Table/CustomerExtension.Table.al"
    "src/Codeunit/SalesProcessor.Codeunit.al"
    "src/Page/CustomerListExt.PageExt.al"
)

Write-ADOSection "Task: Detect Changed AL Files"
Write-ADOSuccess "✓ Found $($changedFiles.Count) changed AL file(s):"
foreach ($file in $changedFiles) {
    Write-ADOInfo " - $file"
}

Write-ADOSection "Task: AI Code Review"
Write-ADOInfo "Provider: github"
Write-ADOInfo "Model: gpt-4o (via model-config.json)"
Write-Host ""
Write-ADOCommand "Invoke-AICodeReview -BaseBranch 'origin/master' -Provider 'github'"
Write-Host ""
Write-ADOInfo "Analyzing code..."
Start-Sleep -Milliseconds 500
Write-ADOInfo "Review completed in 8.3 seconds"

Write-ADOSection "Task: Process Review Results"

# Mock violations (what AI would return)
$violations = @(
    @{
        file = "src/Table/CustomerExtension.Table.al"
        line = 15
        severity = "warning"
        message = "Field name 'customer_id' uses underscores. AL naming convention requires spaces: 'Customer ID'"
    }
    @{
        file = "src/Table/CustomerExtension.Table.al"
        line = 22
        severity = "warning"
        message = "Consider adding ToolTip property for better user experience"
    }
    @{
        file = "src/Codeunit/SalesProcessor.Codeunit.al"
        line = 45
        severity = "error"
        message = "Database access inside repeat loop. Use FindSet() and iterate once, then process records in memory to avoid performance issues"
    }
    @{
        file = "src/Codeunit/SalesProcessor.Codeunit.al"
        line = 67
        severity = "warning"
        message = "Hardcoded text 'Error occurred' should use Label for translation support"
    }
    @{
        file = "src/Codeunit/SalesProcessor.Codeunit.al"
        line = 89
        severity = "error"
        message = "No error handling around database operations. Add try-catch or verify record exists before Get()"
    }
    @{
        file = "src/Page/CustomerListExt.PageExt.al"
        line = 12
        severity = "warning"
        message = "Action placed in wrong group. Finance-related actions should be in 'Processing' group"
    }
)

# Check if module is available
$moduleAvailable = Get-Module -Name "iFacto.AICodeReview" -ListAvailable
if ($moduleAvailable) {
    Write-ADOInfo "Using ConvertTo-ADOLogFormat from installed module..."
    Import-Module iFacto.AICodeReview -Force
    
    # Convert to proper format
    $violationObjects = $violations | ForEach-Object {
        [PSCustomObject]@{
            file = $_.file
            line = $_.line
            severity = $_.severity
            message = $_.message
        }
    }
    
    # Use the module function
    $adoOutput = ConvertTo-ADOLogFormat -Violations $violationObjects
    Write-Host $adoOutput
} else {
    Write-ADOInfo "Formatting violations manually (module not installed)..."
    # Manual formatting
    foreach ($v in $violations) {
        $type = $v.severity
        $logLine = "##vso[task.logissue type=$type;sourcepath=$($v.file);linenumber=$($v.line);]$($v.message)"
        if ($type -eq "error") {
            Write-Host $logLine -ForegroundColor Red
        } else {
            Write-Host $logLine -ForegroundColor Yellow
        }
    }
}

# Count violations
$errorCount = ($violations | Where-Object { $_.severity -eq "error" }).Count
$warningCount = ($violations | Where-Object { $_.severity -eq "warning" }).Count

Write-Host ""
Write-ADOInfo "Total violations: $($violations.Count)"
Write-ADOInfo "Errors: $errorCount"
Write-ADOInfo "Warnings: $warningCount"

# Summary table
Write-Host ""
Write-ADOInfo "Violation Details:"
Write-Host ""

$violations | ForEach-Object {
    [PSCustomObject]@{
        File = [System.IO.Path]::GetFileName($_.file)
        Line = $_.line
        Severity = $_.severity.ToUpper()
        Message = if ($_.message.Length -gt 60) { $_.message.Substring(0, 57) + "..." } else { $_.message }
    }
} | Format-Table -AutoSize

Write-ADOSection "Task: Set Pipeline Result"

$duration = ((Get-Date) - $startTime).TotalSeconds

if ($errorCount -gt 0) {
    Write-ADOError "Build completed with $errorCount error(s)"
    Write-Host "##vso[task.complete result=SucceededWithIssues;]AI Code Review found violations (warnings only in demo)"
    
    Write-Host ""
    Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow
    Write-Host " BUILD SUCCEEDED WITH ISSUES" -ForegroundColor Yellow
    Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow
    Write-ADOInfo "Files reviewed: $($changedFiles.Count)"
    Write-ADOError "Errors: $errorCount"
    Write-ADOWarning "Warnings: $warningCount"
    Write-ADOInfo "Duration: $([math]::Round($duration, 1)) seconds"
    Write-Host ""
} elseif ($warningCount -gt 0) {
    Write-ADOWarning "Build completed with $warningCount warning(s)"
    Write-Host "##vso[task.complete result=SucceededWithIssues;]AI Code Review found warnings"
    
    Write-Host ""
    Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow
    Write-Host " BUILD SUCCEEDED WITH ISSUES" -ForegroundColor Yellow
    Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Yellow
    Write-ADOInfo "Files reviewed: $($changedFiles.Count)"
    Write-ADOWarning "Warnings: $warningCount"
    Write-ADOInfo "Duration: $([math]::Round($duration, 1)) seconds"
    Write-Host ""
} else {
    Write-ADOSuccess "✓ Build succeeded with no issues"
    Write-Host "##vso[task.complete result=Succeeded;]AI Code Review passed"
    
    Write-Host ""
    Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Green
    Write-Host " BUILD SUCCEEDED" -ForegroundColor Green
    Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Green
    Write-ADOInfo "Files reviewed: $($changedFiles.Count)"
    Write-ADOSuccess "Violations: 0"
    Write-ADOInfo "Duration: $([math]::Round($duration, 1)) seconds"
    Write-Host ""
}

Write-Host ""
Write-Host "═══════════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host ""
Write-Host "📖 This demo shows exactly how violations will appear in Azure DevOps" -ForegroundColor Gray
Write-Host " when the AI Code Review module is integrated into your pipeline." -ForegroundColor Gray
Write-Host ""
Write-Host " Each violation includes:" -ForegroundColor Gray
Write-Host " • File path (clickable in ADO)" -ForegroundColor Gray
Write-Host " • Line number (jumps to code in ADO)" -ForegroundColor Gray
Write-Host " • Severity (warning ⚠️ or error ❌)" -ForegroundColor Gray
Write-Host " • AI explanation of the issue" -ForegroundColor Gray
Write-Host ""
Write-Host "═══════════════════════════════════════════════════════════════" -ForegroundColor Cyan
Write-Host ""