# =============================================================================
# AR-Autopilot — developer convenience script (PowerShell, Windows)
# =============================================================================
#
# Usage (from the repo root):
#
#   .\scripts\dev.ps1 <task> [args...]
#
# Tasks:
#
#   install     Install the package + dev dependencies into .venv (creates venv if needed)
#   test        Run the pytest suite
#   test-cov    Run pytest with branch coverage report
#   lint        Run ruff check (no auto-fix)
#   fix         Run ruff check --fix (auto-fix safe findings) then ruff format
#   format      Run ruff format only
#   typecheck   Run mypy --strict over core/library/shared
#   check       Run lint + typecheck + test (the full quality gate)
#   demo        Run examples/sprint0_demo.py
#   clean       Remove build artefacts, __pycache__/, .pytest_cache/, .mypy_cache/, .ruff_cache/
#   help        Show this message
#
# All tasks resolve binaries from .\.venv\Scripts\ — they never depend on
# what's globally installed on the machine.
#
# =============================================================================

[CmdletBinding()]
param(
    [Parameter(Position = 0)]
    [string] $Task = 'help',

    [Parameter(ValueFromRemainingArguments = $true)]
    [string[]] $Args
)

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest

# Resolve repo root regardless of where the script was invoked from.
$RepoRoot = Resolve-Path (Join-Path $PSScriptRoot '..')
Set-Location $RepoRoot

$VenvDir = Join-Path $RepoRoot '.venv'
$VenvScripts = Join-Path $VenvDir 'Scripts'
$Python = Join-Path $VenvScripts 'python.exe'
$Pytest = Join-Path $VenvScripts 'pytest.exe'
$Ruff = Join-Path $VenvScripts 'ruff.exe'
$Mypy = Join-Path $VenvScripts 'mypy.exe'

function Assert-Venv {
    if (-not (Test-Path $Python)) {
        throw "Virtual environment not found at $VenvDir. Run: .\scripts\dev.ps1 install"
    }
}

function Invoke-Install {
    if (-not (Test-Path $Python)) {
        Write-Host "[install] Creating virtual environment at $VenvDir ..."
        & py -m venv $VenvDir
        if ($LASTEXITCODE -ne 0) { throw "venv creation failed (exit $LASTEXITCODE)" }
    }
    Write-Host "[install] Upgrading pip ..."
    & $Python -m pip install --upgrade pip
    if ($LASTEXITCODE -ne 0) { throw "pip upgrade failed" }

    Write-Host "[install] Installing arautopilot[dev] in editable mode ..."
    & $Python -m pip install -e ".[dev]"
    if ($LASTEXITCODE -ne 0) { throw "pip install failed" }

    Write-Host "[install] OK"
}

function Invoke-Test {
    Assert-Venv
    & $Pytest @Args
    exit $LASTEXITCODE
}

function Invoke-TestCov {
    Assert-Venv
    & $Pytest --cov=arautopilot --cov-report=term-missing --cov-report=html @Args
    exit $LASTEXITCODE
}

function Invoke-Lint {
    Assert-Venv
    & $Ruff check arautopilot/
    exit $LASTEXITCODE
}

function Invoke-Fix {
    Assert-Venv
    & $Ruff check arautopilot/ --fix
    $check = $LASTEXITCODE
    & $Ruff format arautopilot/
    $format = $LASTEXITCODE
    if ($check -ne 0) { exit $check }
    exit $format
}

function Invoke-Format {
    Assert-Venv
    & $Ruff format arautopilot/
    exit $LASTEXITCODE
}

function Invoke-Typecheck {
    Assert-Venv
    & $Mypy arautopilot/core arautopilot/library arautopilot/shared
    exit $LASTEXITCODE
}

function Invoke-Check {
    Assert-Venv
    Write-Host "[check] (1/3) lint ..."
    & $Ruff check arautopilot/
    if ($LASTEXITCODE -ne 0) { Write-Host "[check] FAILED at lint"; exit $LASTEXITCODE }

    Write-Host "[check] (2/3) typecheck ..."
    & $Mypy arautopilot/core arautopilot/library arautopilot/shared
    if ($LASTEXITCODE -ne 0) { Write-Host "[check] FAILED at typecheck"; exit $LASTEXITCODE }

    Write-Host "[check] (3/3) tests ..."
    & $Pytest
    if ($LASTEXITCODE -ne 0) { Write-Host "[check] FAILED at tests"; exit $LASTEXITCODE }

    Write-Host "[check] OK"
}

function Invoke-Demo {
    Assert-Venv
    & $Python examples/sprint0_demo.py
    exit $LASTEXITCODE
}

function Invoke-Clean {
    $patterns = @(
        '__pycache__', '.pytest_cache', '.mypy_cache', '.ruff_cache',
        'build', 'dist', '*.egg-info', 'htmlcov', '.coverage'
    )
    foreach ($p in $patterns) {
        Get-ChildItem -Path $RepoRoot -Filter $p -Recurse -Force -ErrorAction SilentlyContinue |
            Where-Object { $_.FullName -notmatch '\\\.venv\\' } |
            ForEach-Object {
                Write-Host "[clean] removing $($_.FullName)"
                Remove-Item -Recurse -Force -LiteralPath $_.FullName -ErrorAction SilentlyContinue
            }
    }
    Get-ChildItem -Path $RepoRoot -Filter '*.pyc' -Recurse -Force -ErrorAction SilentlyContinue |
        ForEach-Object {
            Remove-Item -Force -LiteralPath $_.FullName -ErrorAction SilentlyContinue
        }
    if (Test-Path 'examples/output') {
        Write-Host "[clean] removing examples/output/"
        Remove-Item -Recurse -Force 'examples/output' -ErrorAction SilentlyContinue
    }
    Write-Host "[clean] OK"
}

function Show-Help {
    @'
AR-Autopilot — dev tasks

Usage: .\scripts\dev.ps1 <task> [args...]

Tasks:
  install     Install package + dev deps into .venv (creates venv if needed)
  test        Run pytest
  test-cov    Run pytest with branch coverage
  lint        Run ruff check (read-only)
  fix         Run ruff check --fix + ruff format
  format      Run ruff format
  typecheck   Run mypy --strict
  check       lint + typecheck + test (full quality gate)
  demo        Run examples/sprint0_demo.py
  clean       Remove build / cache artefacts
  help        Show this message

Tip: any extra args are forwarded to the underlying tool, e.g.
     .\scripts\dev.ps1 test -k roundtrip
     .\scripts\dev.ps1 test -v --tb=short
'@ | Write-Host
}

switch ($Task.ToLower()) {
    'install'    { Invoke-Install }
    'test'       { Invoke-Test }
    'test-cov'   { Invoke-TestCov }
    'lint'       { Invoke-Lint }
    'fix'        { Invoke-Fix }
    'format'     { Invoke-Format }
    'typecheck'  { Invoke-Typecheck }
    'check'      { Invoke-Check }
    'demo'       { Invoke-Demo }
    'clean'      { Invoke-Clean }
    'help'       { Show-Help }
    default {
        Write-Host "Unknown task: $Task" -ForegroundColor Red
        Show-Help
        exit 2
    }
}
