param(
    [switch]$RunGodotImport
)

$ErrorActionPreference = "Stop"

$Root = Split-Path -Parent $PSScriptRoot
$Failures = New-Object System.Collections.Generic.List[string]
$Warnings = New-Object System.Collections.Generic.List[string]

function Add-Failure([string]$Message) {
    $Failures.Add($Message) | Out-Null
    Write-Host "[FAIL] $Message"
}

function Add-Warning([string]$Message) {
    $Warnings.Add($Message) | Out-Null
    Write-Host "[WARN] $Message"
}

function Add-Pass([string]$Message) {
    Write-Host "[ OK ] $Message"
}

function Find-Godot {
    if (-not [string]::IsNullOrWhiteSpace($env:GODOT_BIN) -and (Test-Path $env:GODOT_BIN)) {
        return (Resolve-Path $env:GODOT_BIN).Path
    }

    $command = Get-Command godot -ErrorAction SilentlyContinue
    if ($null -ne $command) {
        return $command.Source
    }

    $commonCandidates = @(
        (Join-Path $env:USERPROFILE "Downloads\Godot_v4.6-stable_win64.exe"),
        (Join-Path $env:USERPROFILE "Desktop\Godot_v4.6-stable_win64.exe"),
        (Join-Path $env:LOCALAPPDATA "Programs\Godot\Godot_v4.6-stable_win64.exe"),
        "C:\Program Files\Godot\Godot_v4.6-stable_win64.exe"
    )

    foreach ($candidate in $commonCandidates) {
        if (Test-Path $candidate) {
            return (Resolve-Path $candidate).Path
        }
    }

    return ""
}

Push-Location $Root
try {
    $validateScript = Join-Path $PSScriptRoot "validate_data.ps1"
    if (Test-Path $validateScript) {
        try {
            & $validateScript | Out-Host
            Add-Pass "data validation script passed"
        } catch {
            Add-Failure "data validation failed: $($_.Exception.Message)"
        }
    } else {
        Add-Failure "missing tools\validate_data.ps1"
    }

    $jsonFiles = Get-ChildItem -Path (Join-Path $Root "data") -Filter "*.json" -Recurse
    foreach ($file in $jsonFiles) {
        try {
            Get-Content $file.FullName -Raw | ConvertFrom-Json | Out-Null
        } catch {
            Add-Failure "invalid JSON: $($file.FullName) - $($_.Exception.Message)"
        }
    }
    if ($Failures.Count -eq 0) {
        Add-Pass "all data JSON files parsed"
    }

    $projectPath = Join-Path $Root "project.godot"
    if (Test-Path $projectPath) {
        $projectText = Get-Content $projectPath -Raw
        if ($projectText -match 'config/features=PackedStringArray\("([^"]+)"\)') {
            $featureVersion = $Matches[1]
            if ($featureVersion -ne "4.6") {
                Add-Warning "project feature tag is $featureVersion; expect Godot 4.6 editor migration to update it"
            } else {
                Add-Pass "project feature tag is 4.6"
            }
        } else {
            Add-Warning "project feature tag was not found"
        }

        if ($projectText -match 'renderer/rendering_method="gl_compatibility"') {
            Add-Pass "project keeps the compatibility renderer explicit"
        } else {
            Add-Warning "rendering method is not explicitly gl_compatibility"
        }
    } else {
        Add-Failure "missing project.godot"
    }

    $riskPatterns = [ordered]@{
        "Godot 3 yield syntax" = '\byield\s*\('
        "Godot 3 File.new API" = '\bFile\.new\s*\('
        "Godot 3 Directory.new API" = '\bDirectory\.new\s*\('
        "Godot 3 Pool*Array type" = '\bPool[A-Za-z]+Array\b'
        "Godot 3 KinematicBody node" = '\bKinematicBody(2D|3D)?\b'
        "legacy TileMap set_cellv call" = '\bset_cellv\s*\('
    }

    $gdFiles = Get-ChildItem -Path (Join-Path $Root "scripts") -Filter "*.gd" -Recurse
    foreach ($entry in $riskPatterns.GetEnumerator()) {
        $matches = @()
        foreach ($file in $gdFiles) {
            $fileMatches = Select-String -Path $file.FullName -Pattern $entry.Value -AllMatches
            if ($null -ne $fileMatches) {
                $matches += $fileMatches
            }
        }
        if ($matches.Count -gt 0) {
            Add-Warning "$($entry.Key) found in $($matches.Count) location(s)"
        }
    }
    Add-Pass "static Godot 3 API risk scan completed"

    $godotBin = Find-Godot
    if ([string]::IsNullOrWhiteSpace($godotBin)) {
        Add-Warning "Godot executable not found. Set GODOT_BIN or add godot to PATH for engine checks."
    } else {
        try {
            $version = & $godotBin --version
            Add-Pass "Godot executable found: $godotBin ($version)"
            if ($version -notmatch '^4\.6') {
                Add-Warning "detected Godot version is not 4.6: $version"
            }
            if ($RunGodotImport) {
                & $godotBin --headless --path $Root --quit
                Add-Pass "Godot headless project open completed"
            }
        } catch {
            Add-Failure "Godot command failed: $($_.Exception.Message)"
        }
    }
} finally {
    Pop-Location
}

Write-Host ""
Write-Host "Summary: $($Failures.Count) failure(s), $($Warnings.Count) warning(s)"

if ($Failures.Count -gt 0) {
    exit 1
}

exit 0
