import six
import unicodedata


def GetCharacterDisplayWidth(char):
  """Returns the monospaced terminal display width of char.

  Assumptions:
    - monospaced display
    - ambiguous or unknown chars default to width 1
    - ASCII control char width is 1 => don't use this for control chars

  Args:
    char: The character to determine the display width of.

  Returns:
    The monospaced terminal display width of char: either 0, 1, or 2.
  """
  if not isinstance(char, six.text_type):
    # Non-unicode chars have width 1. Don't use this function on control chars.
    return 1

  # Normalize to avoid special cases.
  char = unicodedata.normalize('NFC', char)

  if unicodedata.combining(char) != 0:
    # Modifies the previous character and does not move the cursor.
    return 0
  elif unicodedata.category(char) == 'Cf':
    # Unprintable formatting char.
    return 0
  elif unicodedata.east_asian_width(char) in 'FW':
    # Fullwidth or Wide chars take 2 character positions.
    return 2
  else:
    # Don't use this function on control chars.
    return 1