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

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

    $commandElements = $commandAst.CommandElements
    $command = @(
        'br'
        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) {
        'br' {
            [CompletionResult]::new('--conf', '--conf', [CompletionResultType]::ParameterName, 'Semicolon separated paths to specific config files')
            [CompletionResult]::new('--max-depth', '--max-depth', [CompletionResultType]::ParameterName, 'Only show trees up to a certain depth')
            [CompletionResult]::new('--outcmd', '--outcmd', [CompletionResultType]::ParameterName, 'Where to write the produced cmd (if any)')
            [CompletionResult]::new('--verb-output', '--verb-output', [CompletionResultType]::ParameterName, 'Optional path for verbs using `:write_output`')
            [CompletionResult]::new('-c', '-c', [CompletionResultType]::ParameterName, 'Semicolon separated commands to execute')
            [CompletionResult]::new('--cmd', '--cmd', [CompletionResultType]::ParameterName, 'Semicolon separated commands to execute')
            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'Whether to have styles and colors')
            [CompletionResult]::new('--height', '--height', [CompletionResultType]::ParameterName, 'Height (if you don''t want to fill the screen or for file export)')
            [CompletionResult]::new('--set-install-state', '--set-install-state', [CompletionResultType]::ParameterName, 'Manually set installation state')
            [CompletionResult]::new('--print-shell-function', '--print-shell-function', [CompletionResultType]::ParameterName, 'Print to stdout the br function for a given shell')
            [CompletionResult]::new('--listen', '--listen', [CompletionResultType]::ParameterName, 'A socket to listen to for commands')
            [CompletionResult]::new('--write-default-conf', '--write-default-conf', [CompletionResultType]::ParameterName, 'Write default conf files in given directory')
            [CompletionResult]::new('--send', '--send', [CompletionResultType]::ParameterName, 'A socket to send commands to')
            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help information')
            [CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'print the version')
            [CompletionResult]::new('-d', '-d', [CompletionResultType]::ParameterName, 'Show the last modified date of files and directories')
            [CompletionResult]::new('--dates', '--dates', [CompletionResultType]::ParameterName, 'Show the last modified date of files and directories')
            [CompletionResult]::new('-D', '-D ', [CompletionResultType]::ParameterName, 'Don''t show the last modified date')
            [CompletionResult]::new('--no-dates', '--no-dates', [CompletionResultType]::ParameterName, 'Don''t show the last modified date')
            [CompletionResult]::new('-f', '-f', [CompletionResultType]::ParameterName, 'Only show folders')
            [CompletionResult]::new('--only-folders', '--only-folders', [CompletionResultType]::ParameterName, 'Only show folders')
            [CompletionResult]::new('-F', '-F ', [CompletionResultType]::ParameterName, 'Show folders and files alike')
            [CompletionResult]::new('--no-only-folders', '--no-only-folders', [CompletionResultType]::ParameterName, 'Show folders and files alike')
            [CompletionResult]::new('--show-root-fs', '--show-root-fs', [CompletionResultType]::ParameterName, 'Show filesystem info on top')
            [CompletionResult]::new('-g', '-g', [CompletionResultType]::ParameterName, 'Show git statuses on files and stats on repo')
            [CompletionResult]::new('--show-git-info', '--show-git-info', [CompletionResultType]::ParameterName, 'Show git statuses on files and stats on repo')
            [CompletionResult]::new('-G', '-G ', [CompletionResultType]::ParameterName, 'Don''t show git statuses on files and stats on repo')
            [CompletionResult]::new('--no-show-git-info', '--no-show-git-info', [CompletionResultType]::ParameterName, 'Don''t show git statuses on files and stats on repo')
            [CompletionResult]::new('--git-status', '--git-status', [CompletionResultType]::ParameterName, 'Only show files having an interesting git status, including hidden ones')
            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Show hidden files')
            [CompletionResult]::new('--hidden', '--hidden', [CompletionResultType]::ParameterName, 'Show hidden files')
            [CompletionResult]::new('-H', '-H ', [CompletionResultType]::ParameterName, 'Don''t show hidden files')
            [CompletionResult]::new('--no-hidden', '--no-hidden', [CompletionResultType]::ParameterName, 'Don''t show hidden files')
            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Show git ignored files')
            [CompletionResult]::new('--git-ignored', '--git-ignored', [CompletionResultType]::ParameterName, 'Show git ignored files')
            [CompletionResult]::new('-I', '-I ', [CompletionResultType]::ParameterName, 'Don''t show git ignored files')
            [CompletionResult]::new('--no-git-ignored', '--no-git-ignored', [CompletionResultType]::ParameterName, 'Don''t show git ignored files')
            [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'Show permissions')
            [CompletionResult]::new('--permissions', '--permissions', [CompletionResultType]::ParameterName, 'Show permissions')
            [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Don''t show permissions')
            [CompletionResult]::new('--no-permissions', '--no-permissions', [CompletionResultType]::ParameterName, 'Don''t show permissions')
            [CompletionResult]::new('-s', '-s', [CompletionResultType]::ParameterName, 'Show the size of files and directories')
            [CompletionResult]::new('--sizes', '--sizes', [CompletionResultType]::ParameterName, 'Show the size of files and directories')
            [CompletionResult]::new('-S', '-S ', [CompletionResultType]::ParameterName, 'Don''t show sizes')
            [CompletionResult]::new('--no-sizes', '--no-sizes', [CompletionResultType]::ParameterName, 'Don''t show sizes')
            [CompletionResult]::new('--sort-by-count', '--sort-by-count', [CompletionResultType]::ParameterName, 'Sort by count (only show one level of the tree)')
            [CompletionResult]::new('--sort-by-date', '--sort-by-date', [CompletionResultType]::ParameterName, 'Sort by date (only show one level of the tree)')
            [CompletionResult]::new('--sort-by-size', '--sort-by-size', [CompletionResultType]::ParameterName, 'Sort by size (only show one level of the tree)')
            [CompletionResult]::new('--sort-by-type', '--sort-by-type', [CompletionResultType]::ParameterName, 'Same as sort-by-type-dirs-first')
            [CompletionResult]::new('--no-tree', '--no-tree', [CompletionResultType]::ParameterName, 'Do not show the tree, even if allowed by sorting mode')
            [CompletionResult]::new('--tree', '--tree', [CompletionResultType]::ParameterName, 'Show the tree, when allowed by sorting mode')
            [CompletionResult]::new('--sort-by-type-dirs-first', '--sort-by-type-dirs-first', [CompletionResultType]::ParameterName, 'Sort by type, directories first (only show one level of the tree)')
            [CompletionResult]::new('--sort-by-type-dirs-last', '--sort-by-type-dirs-last', [CompletionResultType]::ParameterName, 'Sort by type, directories last (only show one level of the tree)')
            [CompletionResult]::new('--no-sort', '--no-sort', [CompletionResultType]::ParameterName, 'Don''t sort')
            [CompletionResult]::new('-w', '-w', [CompletionResultType]::ParameterName, 'Sort by size, show ignored and hidden files')
            [CompletionResult]::new('--whale-spotting', '--whale-spotting', [CompletionResultType]::ParameterName, 'Sort by size, show ignored and hidden files')
            [CompletionResult]::new('-W', '-W ', [CompletionResultType]::ParameterName, 'No sort, no show hidden, no show git ignored')
            [CompletionResult]::new('--no-whale-spotting', '--no-whale-spotting', [CompletionResultType]::ParameterName, 'No sort, no show hidden, no show git ignored')
            [CompletionResult]::new('-t', '-t', [CompletionResultType]::ParameterName, 'Trim the root too and don''t show a scrollbar')
            [CompletionResult]::new('--trim-root', '--trim-root', [CompletionResultType]::ParameterName, 'Trim the root too and don''t show a scrollbar')
            [CompletionResult]::new('-T', '-T ', [CompletionResultType]::ParameterName, 'Don''t trim the root level, show a scrollbar')
            [CompletionResult]::new('--no-trim-root', '--no-trim-root', [CompletionResultType]::ParameterName, 'Don''t trim the root level, show a scrollbar')
            [CompletionResult]::new('--install', '--install', [CompletionResultType]::ParameterName, 'Install or reinstall the br shell function')
            [CompletionResult]::new('--listen-auto', '--listen-auto', [CompletionResultType]::ParameterName, 'create a random socket to listen to for commands')
            [CompletionResult]::new('--get-root', '--get-root', [CompletionResultType]::ParameterName, 'Ask for the current root of the remote broot')
            break
        }
    })

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