# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import signal
import sys

from portage import _unicode_decode
from portage.output import bold, create_color_func


class UserQuery:
    """The UserQuery class is used to prompt the user with a set of responses,
    as well as accepting and handling the responses."""

    def __init__(self, myopts):
        self.myopts = myopts

    def query(self, prompt, enter_invalid, responses=None, colours=None):
        """Display a prompt and a set of responses, then waits for user input
        and check it against the responses. The first match is returned.

        An empty response will match the first value in the list of responses,
        unless enter_invalid is True. The input buffer is *not* cleared prior
        to the prompt!

        prompt: The String to display as a prompt.
        responses: a List of Strings with the acceptable responses.
        colours: a List of Functions taking and returning a String, used to
        process the responses for display. Typically these will be functions
        like red() but could be e.g. lambda x: "DisplayString".

        If responses is omitted, it defaults to ["Yes", "No"], [green, red].
        If only colours is omitted, it defaults to [bold, ...].

        Returns a member of the List responses. (If called without optional
        arguments, it returns "Yes" or "No".)

        KeyboardInterrupt is converted to SystemExit to avoid tracebacks being
        printed."""
        if responses is None:
            responses = ["Yes", "No"]
            colours = [
                create_color_func("PROMPT_CHOICE_DEFAULT"),
                create_color_func("PROMPT_CHOICE_OTHER"),
            ]
        elif colours is None:
            colours = [bold]
        colours = (colours * len(responses))[: len(responses)]
        responses = [_unicode_decode(x) for x in responses]
        if "--alert" in self.myopts:
            prompt = "\a" + prompt
        print(bold(prompt), end=" ")
        try:
            while True:
                try:
                    response = input(
                        "[%s] "
                        % "/".join(
                            [colours[i](responses[i]) for i in range(len(responses))]
                        )
                    )
                except UnicodeDecodeError as e:
                    response = _unicode_decode(e.object).rstrip("\n")
                if response or not enter_invalid:
                    for key in responses:
                        # An empty response will match the
                        # first value in responses.
                        if response.upper() == key[: len(response)].upper():
                            return key
                print("Sorry, response '%s' not understood." % response, end=" ")
        except (EOFError, KeyboardInterrupt):
            print("Interrupted.")
            sys.exit(128 + signal.SIGINT)
