
using namespace System.Management.Automation
using namespace System.Management.Automation.Language

Register-ArgumentCompleter -Native -CommandName 'pibtool' -ScriptBlock {
    param($wordToComplete, $commandAst, $cursorPosition)

    $commandElements = $commandAst.CommandElements
    $command = @(
        'pibtool'
        for ($i = 1; $i -lt $commandElements.Count; $i++) {
            $element = $commandElements[$i]
            if ($element -isnot [StringConstantExpressionAst] -or
                $element.StringConstantType -ne [StringConstantType]::BareWord -or
                $element.Value.StartsWith('-') -or
                $element.Value -eq $wordToComplete) {
                break
        }
        $element.Value
    }) -join ';'

    $completions = @(switch ($command) {
        'pibtool' {
            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
            [CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version')
            [CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
            [CompletionResult]::new('fetch-documents', 'fetch-documents', [CompletionResultType]::ParameterValue, 'Fetch documents from one or multiple authorities')
            [CompletionResult]::new('fetch-borders', 'fetch-borders', [CompletionResultType]::ParameterValue, 'Fetch the borders from the OpenStreetMap overpass API')
            [CompletionResult]::new('check', 'check', [CompletionResultType]::ParameterValue, 'Check that the `pib.json` definition files in the current directory are correct')
            [CompletionResult]::new('generate-website-data', 'generate-website-data', [CompletionResultType]::ParameterValue, 'Generate website data')
            [CompletionResult]::new('generate-shell-completion', 'generate-shell-completion', [CompletionResultType]::ParameterValue, 'Generate shell comletion')
            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
            break
        }
        'pibtool;fetch-documents' {
            [CompletionResult]::new('--only-recent-years', '--only-recent-years', [CompletionResultType]::ParameterName, 'Set the number of recent years which should be checked for new documents')
            [CompletionResult]::new('--force-download', '--force-download', [CompletionResultType]::ParameterName, 'Force a (re-)download, even if the file is already known to `pibtool`')
            [CompletionResult]::new('--recursive', '--recursive', [CompletionResultType]::ParameterName, 'Recurse into subdirectories and download for all authorities found there')
            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'Switch to a more verbose mode. By default, only `info`, `warn` and `error` log levels are printed. Given once, `debug` log level is turned on. Given twice or more, `trace` log level is turned on as well')
            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'Switch to a more verbose mode. By default, only `info`, `warn` and `error` log levels are printed. Given once, `debug` log level is turned on. Given twice or more, `trace` log level is turned on as well')
            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
            break
        }
        'pibtool;fetch-borders' {
            [CompletionResult]::new('--geojson-converter', '--geojson-converter', [CompletionResultType]::ParameterName, 'Convert the download OSM JSON file to GeoJson with this command if present')
            [CompletionResult]::new('--simplify-tolerance', '--simplify-tolerance', [CompletionResultType]::ParameterName, 'Simplify the downloaded borders using the Douglas-Peucker algorithm with the given tolerance')
            [CompletionResult]::new('--force-download', '--force-download', [CompletionResultType]::ParameterName, 'Force a (re-)download,  even if the file is already present')
            [CompletionResult]::new('--recursive', '--recursive', [CompletionResultType]::ParameterName, 'Recurse into subdirectories and download for all authorities found there')
            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
            break
        }
        'pibtool;check' {
            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
            break
        }
        'pibtool;generate-website-data' {
            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
            break
        }
        'pibtool;generate-shell-completion' {
            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help')
            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help')
            break
        }
        'pibtool;help' {
            [CompletionResult]::new('fetch-documents', 'fetch-documents', [CompletionResultType]::ParameterValue, 'Fetch documents from one or multiple authorities')
            [CompletionResult]::new('fetch-borders', 'fetch-borders', [CompletionResultType]::ParameterValue, 'Fetch the borders from the OpenStreetMap overpass API')
            [CompletionResult]::new('check', 'check', [CompletionResultType]::ParameterValue, 'Check that the `pib.json` definition files in the current directory are correct')
            [CompletionResult]::new('generate-website-data', 'generate-website-data', [CompletionResultType]::ParameterValue, 'Generate website data')
            [CompletionResult]::new('generate-shell-completion', 'generate-shell-completion', [CompletionResultType]::ParameterValue, 'Generate shell comletion')
            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
            break
        }
        'pibtool;help;fetch-documents' {
            break
        }
        'pibtool;help;fetch-borders' {
            break
        }
        'pibtool;help;check' {
            break
        }
        'pibtool;help;generate-website-data' {
            break
        }
        'pibtool;help;generate-shell-completion' {
            break
        }
        'pibtool;help;help' {
            break
        }
    })

    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
        Sort-Object -Property ListItemText
}
