# Copyright 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Terminal utilities

This module handles terminal interaction including ANSI color codes.
"""

import os
import sys
from typing import List, Optional

_path = os.path.realpath(__file__ + "/../..")
if sys.path[0] != _path:
    sys.path.insert(0, _path)
del _path

# pylint: disable=wrong-import-position
import rh.shell


# This will erase all content in the current line after the cursor.  This is
# useful for partial updates & progress messages as the terminal can display
# it better.
CSI_ERASE_LINE_AFTER = "\x1b[K"


class Color(object):
    """Conditionally wraps text in ANSI color escape sequences."""

    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
    BOLD = -1
    COLOR_START = "\033[1;%dm"
    BOLD_START = "\033[1m"
    RESET = "\033[m"

    def __init__(self, enabled=None):
        """Create a new Color object, optionally disabling color output.

        Args:
          enabled: True if color output should be enabled.  If False then this
              class will not add color codes at all.
        """
        self._enabled = enabled

    def start(self, color):
        """Returns a start color code.

        Args:
          color: Color to use, e.g. BLACK, RED, etc...

        Returns:
          If color is enabled, returns an ANSI sequence to start the given
          color, otherwise returns empty string
        """
        if self.enabled:
            return self.COLOR_START % (color + 30)
        return ""

    def stop(self):
        """Returns a stop color code.

        Returns:
          If color is enabled, returns an ANSI color reset sequence, otherwise
          returns empty string
        """
        if self.enabled:
            return self.RESET
        return ""

    def color(self, color, text):
        """Returns text with conditionally added color escape sequences.

        Args:
          color: Text color -- one of the color constants defined in this class.
          text: The text to color.

        Returns:
          If self._enabled is False, returns the original text.  If it's True,
          returns text with color escape sequences based on the value of color.
        """
        if not self.enabled:
            return text
        if color == self.BOLD:
            start = self.BOLD_START
        else:
            start = self.COLOR_START % (color + 30)
        return start + text + self.RESET

    @property
    def enabled(self):
        """See if the colorization is enabled."""
        if self._enabled is None:
            if "NOCOLOR" in os.environ:
                self._enabled = not rh.shell.boolean_shell_value(
                    os.environ["NOCOLOR"], False
                )
            else:
                self._enabled = sys.stderr.isatty()
        return self._enabled


def print_status_line(line, print_newline=False):
    """Clears the current terminal line, and prints |line|.

    Args:
      line: String to print.
      print_newline: Print a newline at the end, if sys.stderr is a TTY.
    """
    if sys.stderr.isatty():
        output = "\r" + line + CSI_ERASE_LINE_AFTER
        if print_newline:
            output += "\n"
    else:
        output = line + "\n"

    sys.stderr.write(output)
    sys.stderr.flush()


def str_prompt(
    prompt: str,
    choices: List[str],
    lower: bool = True,
) -> Optional[str]:
    """Helper function for processing user input.

    Args:
        prompt: The question to present to the user.
        lower: Whether to lowercase the response.

    Returns:
        The string the user entered, or None if EOF (e.g. Ctrl+D).
    """
    prompt = f'{prompt} ({"/".join(choices)})? '
    try:
        result = input(prompt)
        return result.lower() if lower else result
    except EOFError:
        # If the user hits Ctrl+D, or stdin is disabled, use the default.
        print()
        return None
    except KeyboardInterrupt:
        # If the user hits Ctrl+C, just exit the process.
        print()
        raise


def boolean_prompt(
    prompt="Do you want to continue?",
    default=True,
    true_value="yes",
    false_value="no",
    prolog=None,
):
    """Helper function for processing boolean choice prompts.

    Args:
      prompt: The question to present to the user.
      default: Boolean to return if the user just presses enter.
      true_value: The text to display that represents a True returned.
      false_value: The text to display that represents a False returned.
      prolog: The text to display before prompt.

    Returns:
      True or False.
    """
    true_value, false_value = true_value.lower(), false_value.lower()
    true_text, false_text = true_value, false_value
    if true_value == false_value:
        raise ValueError(
            f"true_value and false_value must differ: got {true_value!r}"
        )

    if default:
        true_text = true_text[0].upper() + true_text[1:]
    else:
        false_text = false_text[0].upper() + false_text[1:]

    if prolog:
        prompt = f"\n{prolog}\n{prompt}"
    prompt = "\n" + prompt

    while True:
        response = str_prompt(prompt, choices=(true_text, false_text))
        if not response:
            return default
        if true_value.startswith(response):
            if not false_value.startswith(response):
                return True
            # common prefix between the two...
        elif false_value.startswith(response):
            return False
