param(
    [Parameter(Mandatory = $true)][string]$PromptFile,
    [Parameter(Mandatory = $true)][string]$OutputFile,
    [string]$WorkingDirectory = "",
    [switch]$SkipVerdictParse
)

. (Join-Path $PSScriptRoot "Common.ps1")

$codexConfig = Get-CodexConfig
if ([string]::IsNullOrWhiteSpace($WorkingDirectory)) {
    $WorkingDirectory = [string]$codexConfig.working_directory
}

Ensure-Directory -Path (Split-Path -Parent $OutputFile)

$promptText = Get-Content -Raw -Path $PromptFile
$preferredCmd = Join-Path $env:APPDATA "npm\codex.cmd"
$preferredPs1 = Join-Path $env:APPDATA "npm\codex.ps1"
if (Test-Path $preferredCmd) {
    $codexPath = $preferredCmd
}
elseif (Test-Path $preferredPs1) {
    $codexPath = $preferredPs1
}
else {
    $codexCommand = Get-Command codex -ErrorAction SilentlyContinue
    if ($null -eq $codexCommand) {
        throw "codex executable not found in PATH."
    }
    $codexPath = $codexCommand.Source
}

Write-Utf8File -Path $PromptFile -Content $promptText

$stdoutLog = $OutputFile + ".stdout.log"
$stderrLog = $OutputFile + ".stderr.log"
$model = [string]$codexConfig.model
$sessionId = [string]$codexConfig.session_id
if ([string]::IsNullOrWhiteSpace($sessionId)) {
    throw "codex.local.json is missing session_id"
}

$arguments = @(
    "-C", $WorkingDirectory,
    "exec", "resume", $sessionId,
    "--dangerously-bypass-approvals-and-sandbox"
)
if (-not [string]::IsNullOrWhiteSpace($model)) {
    $arguments += @("--model", $model)
}
$arguments += @("--output-last-message", $OutputFile, "-")

$stdout = @()
$stderr = @()
try {
    $mergedOutput = @($promptText | & $codexPath @arguments 2>&1)
    $exitCode = $LASTEXITCODE
    foreach ($entry in $mergedOutput) {
        if ($entry -is [System.Management.Automation.ErrorRecord]) {
            $stderr += $entry.ToString()
        }
        else {
            $stdout += [string]$entry
        }
    }
}
catch {
    $exitCode = 1
    $stderr = @($_.Exception.Message)
}

if ($stdout) {
    Write-Utf8File -Path $stdoutLog -Content ((@($stdout) -join [Environment]::NewLine) + [Environment]::NewLine)
}
elseif (-not (Test-Path $stdoutLog)) {
    Write-Utf8File -Path $stdoutLog -Content ""
}

if ($stderr) {
    Write-Utf8File -Path $stderrLog -Content ((@($stderr) -join [Environment]::NewLine) + [Environment]::NewLine)
}
elseif (-not (Test-Path $stderrLog)) {
    Write-Utf8File -Path $stderrLog -Content ""
}

if (-not $SkipVerdictParse) {
    if (Test-Path $OutputFile) {
        try {
            $parsedVerdict = Read-CodexReviewVerdict -Path $OutputFile
            if ($exitCode -ne 0) {
                $stderr += "Codex returned exit code $exitCode but produced a valid review output. Accepting the review output."
                Write-Utf8File -Path $stderrLog -Content ((@($stderr) -join [Environment]::NewLine) + [Environment]::NewLine)
            }
            return $parsedVerdict
        }
        catch {
            if ($exitCode -eq 0) {
                throw
            }
        }
    }
}
elseif (Test-Path $OutputFile) {
    $rawOutput = (Get-Content -Raw -Path $OutputFile).Trim()
    if (-not [string]::IsNullOrWhiteSpace($rawOutput)) {
        if ($exitCode -ne 0) {
            $stderr += "Codex returned exit code $exitCode but produced non-empty output. Accepting the generated output."
            Write-Utf8File -Path $stderrLog -Content ((@($stderr) -join [Environment]::NewLine) + [Environment]::NewLine)
        }
        return $rawOutput
    }
}

if ($exitCode -ne 0) {
    $errorExcerpt = ""
    $combined = ((@($stdout) + @($stderr)) -join " ").Trim()
    if ($combined -match "usage limit") {
        $errorExcerpt = " Codex local CLI is currently over its usage limit."
    }
    throw "Codex master review failed with exit code $exitCode.$errorExcerpt See $stdoutLog and $stderrLog"
}
