#!/usr/bin/env python
"""A sample application for cmd2.

Thanks to cmd2's built-in transcript testing capability, it also serves as a
test suite for transcript_example.py when used with the transcript_regex.txt transcript.

Running `python transcript_example.py -t transcript_regex.txt` will run all the commands in
the transcript against transcript_example.py, verifying that the output produced matches
the transcript.
"""

import random

import cmd2


class CmdLineApp(cmd2.Cmd):
    """Example cmd2 application."""

    # Setting this true makes it run a shell command if a cmd2/cmd command doesn't exist
    # default_to_shell = True  # noqa: ERA001
    MUMBLES = ('like', '...', 'um', 'er', 'hmmm', 'ahh')
    MUMBLE_FIRST = ('so', 'like', 'well')
    MUMBLE_LAST = ('right?',)

    def __init__(self) -> None:
        shortcuts = cmd2.DEFAULT_SHORTCUTS
        shortcuts.update({'&': 'speak'})
        super().__init__(multiline_commands=['orate'], shortcuts=shortcuts)

        # Make maxrepeats settable at runtime
        self.maxrepeats = 3
        self.add_settable(cmd2.Settable('maxrepeats', int, 'max repetitions for speak command', self))

    speak_parser = cmd2.Cmd2ArgumentParser()
    speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
    speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
    speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
    speak_parser.add_argument('words', nargs='+', help='words to say')

    @cmd2.with_argparser(speak_parser)
    def do_speak(self, args) -> None:
        """Repeats what you tell me to."""
        words = []
        for word in args.words:
            if args.piglatin:
                word = f'{word[1:]}{word[0]}ay'
            if args.shout:
                word = word.upper()
            words.append(word)
        repetitions = args.repeat or 1
        for _ in range(min(repetitions, self.maxrepeats)):
            # .poutput handles newlines, and accommodates output redirection too
            self.poutput(' '.join(words))

    do_say = do_speak  # now "say" is a synonym for "speak"
    do_orate = do_speak  # another synonym, but this one takes multi-line input

    mumble_parser = cmd2.Cmd2ArgumentParser()
    mumble_parser.add_argument('-r', '--repeat', type=int, help='how many times to repeat')
    mumble_parser.add_argument('words', nargs='+', help='words to say')

    @cmd2.with_argparser(mumble_parser)
    def do_mumble(self, args) -> None:
        """Mumbles what you tell me to."""
        repetitions = args.repeat or 1
        for _ in range(min(repetitions, self.maxrepeats)):
            output = []
            if random.random() < 0.33:
                output.append(random.choice(self.MUMBLE_FIRST))
            for word in args.words:
                if random.random() < 0.40:
                    output.append(random.choice(self.MUMBLES))
                output.append(word)
            if random.random() < 0.25:
                output.append(random.choice(self.MUMBLE_LAST))
            self.poutput(' '.join(output))


if __name__ == '__main__':
    import sys

    c = CmdLineApp()
    sys.exit(c.cmdloop())
