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

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

    $commandElements = $commandAst.CommandElements
    $command = @(
        'asciinema'
        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) {
        'asciinema' {
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
            [CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version')
            [CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version')
            [CompletionResult]::new('record', 'record', [CompletionResultType]::ParameterValue, 'Record a terminal session')
            [CompletionResult]::new('rec', 'rec', [CompletionResultType]::ParameterValue, 'Record a terminal session')
            [CompletionResult]::new('stream', 'stream', [CompletionResultType]::ParameterValue, 'Stream a terminal session')
            [CompletionResult]::new('session', 'session', [CompletionResultType]::ParameterValue, 'Record and stream a terminal session')
            [CompletionResult]::new('play', 'play', [CompletionResultType]::ParameterValue, 'Play back a terminal session')
            [CompletionResult]::new('upload', 'upload', [CompletionResultType]::ParameterValue, 'Upload a recording to an asciinema server')
            [CompletionResult]::new('auth', 'auth', [CompletionResultType]::ParameterValue, 'Authenticate this CLI with an asciinema server account')
            [CompletionResult]::new('cat', 'cat', [CompletionResultType]::ParameterValue, 'Concatenate multiple recordings')
            [CompletionResult]::new('convert', 'convert', [CompletionResultType]::ParameterValue, 'Convert a recording to another format')
            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
            break
        }
        'asciinema;record' {
            [CompletionResult]::new('-f', '-f', [CompletionResultType]::ParameterName, 'Output file format [default: asciicast-v3]')
            [CompletionResult]::new('--output-format', '--output-format', [CompletionResultType]::ParameterName, 'Output file format [default: asciicast-v3]')
            [CompletionResult]::new('-c', '-c', [CompletionResultType]::ParameterName, 'Command to start in the session [default: $SHELL]')
            [CompletionResult]::new('--command', '--command', [CompletionResultType]::ParameterName, 'Command to start in the session [default: $SHELL]')
            [CompletionResult]::new('--capture-env', '--capture-env', [CompletionResultType]::ParameterName, 'Comma-separated list of environment variables to capture [default: SHELL]')
            [CompletionResult]::new('-t', '-t', [CompletionResultType]::ParameterName, 'Title of the recording')
            [CompletionResult]::new('--title', '--title', [CompletionResultType]::ParameterName, 'Title of the recording')
            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Limit idle time to a given number of seconds')
            [CompletionResult]::new('--idle-time-limit', '--idle-time-limit', [CompletionResultType]::ParameterName, 'Limit idle time to a given number of seconds')
            [CompletionResult]::new('--window-size', '--window-size', [CompletionResultType]::ParameterName, 'Override session''s terminal window size')
            [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Log file path')
            [CompletionResult]::new('--cols', '--cols', [CompletionResultType]::ParameterName, 'cols')
            [CompletionResult]::new('--rows', '--rows', [CompletionResultType]::ParameterName, 'rows')
            [CompletionResult]::new('-I', '-I ', [CompletionResultType]::ParameterName, 'Enable input (keyboard) capture')
            [CompletionResult]::new('--capture-input', '--capture-input', [CompletionResultType]::ParameterName, 'Enable input (keyboard) capture')
            [CompletionResult]::new('-a', '-a', [CompletionResultType]::ParameterName, 'Append to an existing recording file')
            [CompletionResult]::new('--append', '--append', [CompletionResultType]::ParameterName, 'Append to an existing recording file')
            [CompletionResult]::new('--overwrite', '--overwrite', [CompletionResultType]::ParameterName, 'Overwrite the output file if it already exists')
            [CompletionResult]::new('--headless', '--headless', [CompletionResultType]::ParameterName, 'Headless mode - don''t use the terminal for I/O')
            [CompletionResult]::new('--return', '--return', [CompletionResultType]::ParameterName, 'Return the session''s exit status')
            [CompletionResult]::new('--raw', '--raw', [CompletionResultType]::ParameterName, 'raw')
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [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
        }
        'asciinema;rec' {
            [CompletionResult]::new('-f', '-f', [CompletionResultType]::ParameterName, 'Output file format [default: asciicast-v3]')
            [CompletionResult]::new('--output-format', '--output-format', [CompletionResultType]::ParameterName, 'Output file format [default: asciicast-v3]')
            [CompletionResult]::new('-c', '-c', [CompletionResultType]::ParameterName, 'Command to start in the session [default: $SHELL]')
            [CompletionResult]::new('--command', '--command', [CompletionResultType]::ParameterName, 'Command to start in the session [default: $SHELL]')
            [CompletionResult]::new('--capture-env', '--capture-env', [CompletionResultType]::ParameterName, 'Comma-separated list of environment variables to capture [default: SHELL]')
            [CompletionResult]::new('-t', '-t', [CompletionResultType]::ParameterName, 'Title of the recording')
            [CompletionResult]::new('--title', '--title', [CompletionResultType]::ParameterName, 'Title of the recording')
            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Limit idle time to a given number of seconds')
            [CompletionResult]::new('--idle-time-limit', '--idle-time-limit', [CompletionResultType]::ParameterName, 'Limit idle time to a given number of seconds')
            [CompletionResult]::new('--window-size', '--window-size', [CompletionResultType]::ParameterName, 'Override session''s terminal window size')
            [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Log file path')
            [CompletionResult]::new('--cols', '--cols', [CompletionResultType]::ParameterName, 'cols')
            [CompletionResult]::new('--rows', '--rows', [CompletionResultType]::ParameterName, 'rows')
            [CompletionResult]::new('-I', '-I ', [CompletionResultType]::ParameterName, 'Enable input (keyboard) capture')
            [CompletionResult]::new('--capture-input', '--capture-input', [CompletionResultType]::ParameterName, 'Enable input (keyboard) capture')
            [CompletionResult]::new('-a', '-a', [CompletionResultType]::ParameterName, 'Append to an existing recording file')
            [CompletionResult]::new('--append', '--append', [CompletionResultType]::ParameterName, 'Append to an existing recording file')
            [CompletionResult]::new('--overwrite', '--overwrite', [CompletionResultType]::ParameterName, 'Overwrite the output file if it already exists')
            [CompletionResult]::new('--headless', '--headless', [CompletionResultType]::ParameterName, 'Headless mode - don''t use the terminal for I/O')
            [CompletionResult]::new('--return', '--return', [CompletionResultType]::ParameterName, 'Return the session''s exit status')
            [CompletionResult]::new('--raw', '--raw', [CompletionResultType]::ParameterName, 'raw')
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [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
        }
        'asciinema;stream' {
            [CompletionResult]::new('-l', '-l', [CompletionResultType]::ParameterName, 'Stream via the local HTTP server')
            [CompletionResult]::new('--local', '--local', [CompletionResultType]::ParameterName, 'Stream via the local HTTP server')
            [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Stream via remote asciinema server')
            [CompletionResult]::new('--remote', '--remote', [CompletionResultType]::ParameterName, 'Stream via remote asciinema server')
            [CompletionResult]::new('-c', '-c', [CompletionResultType]::ParameterName, 'Command to start in the session [default: $SHELL]')
            [CompletionResult]::new('--command', '--command', [CompletionResultType]::ParameterName, 'Command to start in the session [default: $SHELL]')
            [CompletionResult]::new('--capture-env', '--capture-env', [CompletionResultType]::ParameterName, 'Comma-separated list of environment variables to capture [default: SHELL]')
            [CompletionResult]::new('-t', '-t', [CompletionResultType]::ParameterName, 'Title of the session')
            [CompletionResult]::new('--title', '--title', [CompletionResultType]::ParameterName, 'Title of the session')
            [CompletionResult]::new('--description', '--description', [CompletionResultType]::ParameterName, 'Description of the session (Markdown supported)')
            [CompletionResult]::new('--visibility', '--visibility', [CompletionResultType]::ParameterName, 'Visibility level')
            [CompletionResult]::new('--audio-url', '--audio-url', [CompletionResultType]::ParameterName, 'Audio stream URL for synchronized playback')
            [CompletionResult]::new('--window-size', '--window-size', [CompletionResultType]::ParameterName, 'Override session''s terminal window size')
            [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Log file path')
            [CompletionResult]::new('--server-url', '--server-url', [CompletionResultType]::ParameterName, 'asciinema server URL')
            [CompletionResult]::new('-I', '-I ', [CompletionResultType]::ParameterName, 'Enable input (keyboard) capture')
            [CompletionResult]::new('--capture-input', '--capture-input', [CompletionResultType]::ParameterName, 'Enable input (keyboard) capture')
            [CompletionResult]::new('--headless', '--headless', [CompletionResultType]::ParameterName, 'Headless mode - don''t use the terminal for I/O')
            [CompletionResult]::new('--return', '--return', [CompletionResultType]::ParameterName, 'Return the session''s exit status')
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [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
        }
        'asciinema;session' {
            [CompletionResult]::new('-o', '-o', [CompletionResultType]::ParameterName, 'Save the session to a file')
            [CompletionResult]::new('--output-file', '--output-file', [CompletionResultType]::ParameterName, 'Save the session to a file')
            [CompletionResult]::new('-f', '-f', [CompletionResultType]::ParameterName, 'Output file format [default: asciicast-v3]')
            [CompletionResult]::new('--output-format', '--output-format', [CompletionResultType]::ParameterName, 'Output file format [default: asciicast-v3]')
            [CompletionResult]::new('-l', '-l', [CompletionResultType]::ParameterName, 'Stream via the local HTTP server')
            [CompletionResult]::new('--stream-local', '--stream-local', [CompletionResultType]::ParameterName, 'Stream via the local HTTP server')
            [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Stream via remote asciinema server')
            [CompletionResult]::new('--stream-remote', '--stream-remote', [CompletionResultType]::ParameterName, 'Stream via remote asciinema server')
            [CompletionResult]::new('-c', '-c', [CompletionResultType]::ParameterName, 'Command to start in the session [default: $SHELL]')
            [CompletionResult]::new('--command', '--command', [CompletionResultType]::ParameterName, 'Command to start in the session [default: $SHELL]')
            [CompletionResult]::new('--capture-env', '--capture-env', [CompletionResultType]::ParameterName, 'Comma-separated list of environment variables to capture [default: SHELL]')
            [CompletionResult]::new('-t', '-t', [CompletionResultType]::ParameterName, 'Title of the session')
            [CompletionResult]::new('--title', '--title', [CompletionResultType]::ParameterName, 'Title of the session')
            [CompletionResult]::new('--description', '--description', [CompletionResultType]::ParameterName, 'Description of the session (Markdown supported)')
            [CompletionResult]::new('--visibility', '--visibility', [CompletionResultType]::ParameterName, 'Stream visibility level')
            [CompletionResult]::new('--audio-url', '--audio-url', [CompletionResultType]::ParameterName, 'Audio stream URL for synchronized playback')
            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Limit idle time to a given number of seconds')
            [CompletionResult]::new('--idle-time-limit', '--idle-time-limit', [CompletionResultType]::ParameterName, 'Limit idle time to a given number of seconds')
            [CompletionResult]::new('--window-size', '--window-size', [CompletionResultType]::ParameterName, 'Override session''s terminal window size')
            [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Log file path')
            [CompletionResult]::new('--server-url', '--server-url', [CompletionResultType]::ParameterName, 'asciinema server URL')
            [CompletionResult]::new('-I', '-I ', [CompletionResultType]::ParameterName, 'Enable input (keyboard) capture')
            [CompletionResult]::new('--capture-input', '--capture-input', [CompletionResultType]::ParameterName, 'Enable input (keyboard) capture')
            [CompletionResult]::new('-a', '-a', [CompletionResultType]::ParameterName, 'Append to an existing recording file')
            [CompletionResult]::new('--append', '--append', [CompletionResultType]::ParameterName, 'Append to an existing recording file')
            [CompletionResult]::new('--overwrite', '--overwrite', [CompletionResultType]::ParameterName, 'Overwrite the output file if it already exists')
            [CompletionResult]::new('--headless', '--headless', [CompletionResultType]::ParameterName, 'Headless mode - don''t use the terminal for I/O')
            [CompletionResult]::new('--return', '--return', [CompletionResultType]::ParameterName, 'Return the session''s exit status')
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [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
        }
        'asciinema;play' {
            [CompletionResult]::new('-s', '-s', [CompletionResultType]::ParameterName, 'Set playback speed')
            [CompletionResult]::new('--speed', '--speed', [CompletionResultType]::ParameterName, 'Set playback speed')
            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Limit idle time to a given number of seconds')
            [CompletionResult]::new('--idle-time-limit', '--idle-time-limit', [CompletionResultType]::ParameterName, 'Limit idle time to a given number of seconds')
            [CompletionResult]::new('-l', '-l', [CompletionResultType]::ParameterName, 'Loop playback continuously')
            [CompletionResult]::new('--loop', '--loop', [CompletionResultType]::ParameterName, 'Loop playback continuously')
            [CompletionResult]::new('-m', '-m', [CompletionResultType]::ParameterName, 'Automatically pause on markers')
            [CompletionResult]::new('--pause-on-markers', '--pause-on-markers', [CompletionResultType]::ParameterName, 'Automatically pause on markers')
            [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Auto-resize terminal to match original size')
            [CompletionResult]::new('--resize', '--resize', [CompletionResultType]::ParameterName, 'Auto-resize terminal to match original size')
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [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
        }
        'asciinema;upload' {
            [CompletionResult]::new('-t', '-t', [CompletionResultType]::ParameterName, 'Title of the recording')
            [CompletionResult]::new('--title', '--title', [CompletionResultType]::ParameterName, 'Title of the recording')
            [CompletionResult]::new('--description', '--description', [CompletionResultType]::ParameterName, 'Description of the recording (Markdown supported)')
            [CompletionResult]::new('--visibility', '--visibility', [CompletionResultType]::ParameterName, 'Recording visibility level')
            [CompletionResult]::new('--audio-url', '--audio-url', [CompletionResultType]::ParameterName, 'Audio URL for synchronized playback')
            [CompletionResult]::new('--server-url', '--server-url', [CompletionResultType]::ParameterName, 'asciinema server URL')
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [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
        }
        'asciinema;auth' {
            [CompletionResult]::new('--server-url', '--server-url', [CompletionResultType]::ParameterName, 'asciinema server URL')
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [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
        }
        'asciinema;cat' {
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [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
        }
        'asciinema;convert' {
            [CompletionResult]::new('-f', '-f', [CompletionResultType]::ParameterName, 'Output file format [default: asciicast-v3]')
            [CompletionResult]::new('--output-format', '--output-format', [CompletionResultType]::ParameterName, 'Output file format [default: asciicast-v3]')
            [CompletionResult]::new('--overwrite', '--overwrite', [CompletionResultType]::ParameterName, 'Overwrite the output file if it already exists')
            [CompletionResult]::new('-q', '-q', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Quiet mode - suppress diagnostic messages')
            [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
        }
        'asciinema;help' {
            [CompletionResult]::new('record', 'record', [CompletionResultType]::ParameterValue, 'Record a terminal session')
            [CompletionResult]::new('stream', 'stream', [CompletionResultType]::ParameterValue, 'Stream a terminal session')
            [CompletionResult]::new('session', 'session', [CompletionResultType]::ParameterValue, 'Record and stream a terminal session')
            [CompletionResult]::new('play', 'play', [CompletionResultType]::ParameterValue, 'Play back a terminal session')
            [CompletionResult]::new('upload', 'upload', [CompletionResultType]::ParameterValue, 'Upload a recording to an asciinema server')
            [CompletionResult]::new('auth', 'auth', [CompletionResultType]::ParameterValue, 'Authenticate this CLI with an asciinema server account')
            [CompletionResult]::new('cat', 'cat', [CompletionResultType]::ParameterValue, 'Concatenate multiple recordings')
            [CompletionResult]::new('convert', 'convert', [CompletionResultType]::ParameterValue, 'Convert a recording to another format')
            [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)')
            break
        }
        'asciinema;help;record' {
            break
        }
        'asciinema;help;stream' {
            break
        }
        'asciinema;help;session' {
            break
        }
        'asciinema;help;play' {
            break
        }
        'asciinema;help;upload' {
            break
        }
        'asciinema;help;auth' {
            break
        }
        'asciinema;help;cat' {
            break
        }
        'asciinema;help;convert' {
            break
        }
        'asciinema;help;help' {
            break
        }
    })

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