import six


def canonicalize_monotonicity(monotonicity, allow_decreasing=True):
  """Converts string constants representing monotonicity into integers.

  Args:
    monotonicity: The monotonicities hyperparameter of a `tfl.layers` Layer
      (e.g. `tfl.layers.PWLCalibration`).
    allow_decreasing: If decreasing monotonicity is considered a valid
      monotonicity.

  Returns:
    monotonicity represented as -1, 0, 1, or None.

  Raises:
    ValueError: If monotonicity is not in the set
      {-1, 0, 1, 'decreasing', 'none', 'increasing'} and allow_decreasing is
      True.
    ValueError: If monotonicity is not in the set {0, 1, 'none', 'increasing'}
      and allow_decreasing is False.
  """
  if monotonicity is None:
    return None

  if monotonicity in [-1, 0, 1]:
    if not allow_decreasing and monotonicity == -1:
      raise ValueError(
          "'monotonicities' must be from: [0, 1, 'none', 'increasing']. "
          "Given: {}".format(monotonicity))
    return monotonicity
  elif isinstance(monotonicity, six.string_types):
    if monotonicity.lower() == "decreasing":
      if not allow_decreasing:
        raise ValueError(
            "'monotonicities' must be from: [0, 1, 'none', 'increasing']. "
            "Given: {}".format(monotonicity))
      return -1
    if monotonicity.lower() == "none":
      return 0
    if monotonicity.lower() == "increasing":
      return 1
  raise ValueError("'monotonicities' must be from: [-1, 0, 1, 'decreasing', "
                   "'none', 'increasing']. Given: {}".format(monotonicity))