# cost-budget-gate.ps1 -- PreToolUse hook
# Blocks LLM calls when agent has exceeded its per-session token budget.
# Exit code 2 = block. Exit code 0 = allow.
#
# Part of @connexum/ai-governance

$ErrorActionPreference = 'Stop'

$rawInput = [Console]::In.ReadToEnd()

if ([string]::IsNullOrWhiteSpace($rawInput)) { exit 0 }

try { $input_obj = $rawInput | ConvertFrom-Json } catch { exit 0 }

$toolName = if ($input_obj.tool_name) { $input_obj.tool_name } else { '' }

# Only gate Agent tool (which spawns LLM calls)
if ($toolName -ne 'Agent') { exit 0 }

# Check if budget tracking is enabled
$budgetFile = $null
foreach ($candidate in @(
    '.claude/governance/token-budget.json',
    '.claude/cost-tracking/budget.json',
    'GOVERNANCE/token-budget.json'
)) {
    if (Test-Path $candidate) {
        $budgetFile = $candidate
        break
    }
}

# If no budget file, allow (no budget configured)
if (-not $budgetFile) { exit 0 }

# Read budget limits
try {
    $budget = Get-Content $budgetFile -Raw | ConvertFrom-Json
} catch {
    exit 0
}

$maxTokens = if ($budget.max_session_tokens) { [int]$budget.max_session_tokens } else { 0 }
$currentTokens = if ($budget.current_session_tokens) { [int]$budget.current_session_tokens } else { 0 }
$maxCostUsd = if ($budget.max_session_cost_usd) { [double]$budget.max_session_cost_usd } else { 0 }
$currentCostUsd = if ($budget.current_session_cost_usd) { [double]$budget.current_session_cost_usd } else { 0 }

# Check token budget
if ($maxTokens -gt 0 -and $currentTokens -ge $maxTokens) {
    [Console]::Error.WriteLine("BLOCKED: Token budget exceeded. Used $currentTokens / $maxTokens tokens this session.")
    [Console]::Error.WriteLine("Increase budget in $budgetFile or start a new session.")
    exit 2
}

# Check cost budget
if ($maxCostUsd -gt 0 -and $currentCostUsd -ge $maxCostUsd) {
    [Console]::Error.WriteLine("BLOCKED: Cost budget exceeded. Spent `$$currentCostUsd / `$$maxCostUsd this session.")
    exit 2
}

exit 0
