Describe 'task-stubs' {
    BeforeAll {
        $originalPath = Get-Location
        # The workflow sets this for the whole job and Pester runs every suite in one process, so
        # put back what was there rather than dropping it.
        $originalTrustedConfigPaths = [Environment]::GetEnvironmentVariable('MISE_TRUSTED_CONFIG_PATHS', 'Process')
        Set-Location TestDrive:
        $env:MISE_TRUSTED_CONFIG_PATHS = $TestDrive

        @'
[tasks.hello]
run = "echo hi-from-task"

[tasks."build:all"]
run = "echo hi-from-nested"
'@ | Out-File -FilePath 'mise.toml' -Encoding utf8NoBOM

        mise generate task-stubs | Out-Null
    }

    AfterAll {
        Set-Location $originalPath
        if ($null -eq $originalTrustedConfigPaths) {
            Remove-Item -Path Env:\MISE_TRUSTED_CONFIG_PATHS -ErrorAction SilentlyContinue
        } else {
            [Environment]::SetEnvironmentVariable('MISE_TRUSTED_CONFIG_PATHS', $originalTrustedConfigPaths, 'Process')
        }
    }

    It 'writes a .cmd launcher beside each stub' {
        # Windows will not execute the `#!/bin/sh` stub, so without this there is nothing to run.
        Test-Path 'bin\hello' | Should -BeTrue
        Test-Path 'bin\hello.cmd' | Should -BeTrue
        (Get-Content 'bin\hello.cmd' -Raw) | Should -BeLike '*"mise" run "hello" %`**'
        # Ownership marker: what regeneration and cleanup use to tell our file from the user's.
        (Get-Content 'bin\hello.cmd' -Raw) | Should -BeLike '*rem generated by mise*'
    }

    It 'refuses to overwrite a hand-written launcher' {
        New-Item -ItemType Directory -Force 'owned-bin' | Out-Null
        "@echo off`r`necho mine`r`n" | Out-File -FilePath 'owned-bin\hello.cmd' -Encoding utf8NoBOM -NoNewline
        mise generate task-stubs --dir owned-bin 2>&1 | Out-String |
            Should -BeLike '*is not a generated launcher*'
        (Get-Content 'owned-bin\hello.cmd' -Raw) | Should -BeLike '*echo mine*'
        # Validation runs before anything is written, so the stub is not there either.
        Test-Path 'owned-bin\hello' | Should -BeFalse
    }

    It 'runs the task through the launcher' {
        # The point of the change: not that the file exists, but that it works.
        & '.\bin\hello.cmd' | Select-Object -Last 1 | Should -Be 'hi-from-task'
    }

    It 'covers nested tasks too' {
        Test-Path 'bin\build\all.cmd' | Should -BeTrue
        & '.\bin\build\all.cmd' | Select-Object -Last 1 | Should -Be 'hi-from-nested'
    }

    It 'forwards arguments' {
        @'
[tasks.echoer]
run = "echo got"
'@ | Out-File -FilePath 'mise.toml' -Encoding utf8NoBOM -Append
        mise generate task-stubs | Out-Null
        & '.\bin\echoer.cmd' extra | Select-Object -Last 1 | Should -BeLike '*extra*'
    }

    It 'is idempotent' {
        # Regeneration walks the existing stub tree and refuses anything it did not write, so the
        # launchers have to be recognised as generated or the second run fails.
        mise generate task-stubs | Out-Null
        mise generate task-stubs | Out-Null
        Test-Path 'bin\hello.cmd' | Should -BeTrue
        & '.\bin\hello.cmd' | Select-Object -Last 1 | Should -Be 'hi-from-task'
    }
}
