# Copyright 2016 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""User input handlers."""


class InputError(Exception):
    """An error with a user provided input."""


class _InputHandler(object):
    """An input handler base class."""

    def get_choices_supplements(self):
        """Returns a pair of supplement strings representing input choices.

        @return: A pair consisting of a detailed representation of available
                 choices, and a corresponding concise descriptor of available
                 input choices with optional default.
        """
        input_choices, default = self._get_input_choices_and_default()
        if input_choices:
            input_choices = '[%s]' % input_choices
            if default is not None:
                input_choices += ' (default: %s)' % default

        return self._get_choices_details(), input_choices


    def _get_input_choices_and_default(self):
        """Returns an input choices descriptor and a default (if any)."""
        raise NotImplementedError


    def _get_choices_details(self):
        """Returns a detailed description (string) of input choices."""
        raise NotImplementedError


    def process(self, input_str):
        """Returns the result of processing the user input.

        @param input_str: The user input.

        @return: The result of processing the input.

        @raise InputError: Provided input is invalid.
        """
        raise NotImplementedError


class PauseInputHandler(_InputHandler):
    """A quiet input handler that just returns on any input."""

    # Interface overrides.
    #
    def _get_input_choices_and_default(self):
        return None, None


    def _get_choices_details(self):
        return None


    def process(self, input_str):
        pass


class YesNoInputHandler(_InputHandler):
    "A yes/no input handler with optional default."""

    def __init__(self, default=None):
        """Initializes the input handler.

        @param default: The Boolean value to return by default.
        """
        self._default = default
        self._input_choices = '%s/%s' % ('Y' if default is True else 'y',
                                         'N' if default is False else 'n')


    # Interface overrides.
    #
    def _get_input_choices_and_default(self):
        # We highlight the default by uppercasing the corresponding choice
        # directly, so no need to return a default separately.
        return self._input_choices, None


    def _get_choices_details(self):
        return None


    def process(self, input_str):
        input_str = input_str.lower().strip()
        if input_str == 'y':
            return True
        if input_str == 'n':
            return False
        if not input_str and self._default is not None:
            return self._default
        raise InputError


class MultipleChoiceInputHandler(_InputHandler):
    """A multiple choice input handler with optional default."""

    def __init__(self, choices, default=None):
        """Initializes the input handler.

        @param choices: An iterable of input choices.
        @param default: Index of default choice (integer).
        """
        max_idx = len(choices)
        if not (default is None or default in range(1, max_idx + 1)):
            raise ValueError('Default choice is not a valid index')
        self._choices = choices
        self._idx_range = '1-%d' % max_idx if max_idx > 1 else str(max_idx)
        self._default = None if default is None else str(default)


    # Interface overrides.
    #
    def _get_input_choices_and_default(self):
        return self._idx_range, self._default


    def _get_choices_details(self):
        return '\n'.join(['%d) %s' % (idx, choice)
                          for idx, choice in enumerate(self._choices, 1)])


    def process(self, input_str):
        """Returns the index (zero-based) and value of the chosen option."""
        input_str = input_str or self._default
        if input_str:
            try:
                input_idx = int(input_str) - 1
                if input_idx in range(len(self._choices)):
                    return input_idx, self._choices[input_idx]
            except ValueError:
                pass

        raise InputError
