# Copyright 2017 The Abseil Authors.
#
# 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.

"""Module to convert log levels between Abseil Python, C++, and Python standard.

This converter has to convert (best effort) between three different
logging level schemes:
  cpp      = The C++ logging level scheme used in Abseil C++.
  absl     = The absl.logging level scheme used in Abseil Python.
  standard = The python standard library logging level scheme.

Here is a handy ascii chart for easy mental mapping.

  LEVEL     | cpp |  absl  | standard |
  ----------+-----+--------+----------+
  DEBUG     |  0  |    1   |    10    |
  INFO      |  0  |    0   |    20    |
  WARN(ING) |  1  |   -1   |    30    |
  ERROR     |  2  |   -2   |    40    |
  CRITICAL  |  3  |   -3   |    50    |
  FATAL     |  3  |   -3   |    50    |

Note: standard logging CRITICAL is mapped to absl/cpp FATAL.
However, only CRITICAL logs from the absl logger (or absl.logging.fatal) will
terminate the program. CRITICAL logs from non-absl loggers are treated as
error logs with a message prefix "CRITICAL - ".

Converting from standard to absl or cpp is a lossy conversion.
Converting back to standard will lose granularity.  For this reason,
users should always try to convert to standard, the richest
representation, before manipulating the levels, and then only to cpp
or absl if those level schemes are absolutely necessary.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import logging

STANDARD_CRITICAL = logging.CRITICAL
STANDARD_ERROR = logging.ERROR
STANDARD_WARNING = logging.WARNING
STANDARD_INFO = logging.INFO
STANDARD_DEBUG = logging.DEBUG

# These levels are also used to define the constants
# FATAL, ERROR, WARN, WARNING, INFO, and DEBUG in the
# absl.logging module.
ABSL_FATAL = -3
ABSL_ERROR = -2
ABSL_WARN = -1
ABSL_INFO = 0
ABSL_DEBUG = 1

ABSL_LEVELS = {ABSL_FATAL: 'FATAL',
               ABSL_ERROR: 'ERROR',
               ABSL_WARN: 'WARN',
               ABSL_INFO: 'INFO',
               ABSL_DEBUG: 'DEBUG'}

# Inverts the ABSL_LEVELS dictionary
ABSL_NAMES = dict((v, k) for (k, v) in ABSL_LEVELS.items())

ABSL_TO_STANDARD = {ABSL_FATAL: STANDARD_CRITICAL,
                    ABSL_ERROR: STANDARD_ERROR,
                    ABSL_WARN: STANDARD_WARNING,
                    ABSL_INFO: STANDARD_INFO,
                    ABSL_DEBUG: STANDARD_DEBUG}

# Inverts the ABSL_TO_STANDARD
STANDARD_TO_ABSL = dict((v, k) for (k, v) in ABSL_TO_STANDARD.items())


def get_initial_for_level(level):
  """Gets the initial that should start the log line for the given level.

  It returns:
  - 'I' when: level < STANDARD_WARNING.
  - 'W' when: STANDARD_WARNING <= level < STANDARD_ERROR.
  - 'E' when: STANDARD_ERROR <= level < STANDARD_CRITICAL.
  - 'F' when: level >= STANDARD_CRITICAL.

  Args:
    level: int, a Python standard logging level.

  Returns:
    The first initial as it would be logged by the C++ logging module.
  """
  if level < STANDARD_WARNING:
    return 'I'
  elif level < STANDARD_ERROR:
    return 'W'
  elif level < STANDARD_CRITICAL:
    return 'E'
  else:
    return 'F'


def absl_to_cpp(level):
  """Converts an absl log level to a cpp log level.

  Args:
    level: int, an absl.logging level.

  Raises:
    TypeError: Raised when level is not an integer.

  Returns:
    The corresponding integer level for use in Abseil C++.
  """
  if not isinstance(level, int):
    raise TypeError('Expect an int level, found {}'.format(type(level)))
  if level >= 0:
    # C++ log levels must be >= 0
    return 0
  else:
    return -level


def absl_to_standard(level):
  """Converts an integer level from the absl value to the standard value.

  Args:
    level: int, an absl.logging level.

  Raises:
    TypeError: Raised when level is not an integer.

  Returns:
    The corresponding integer level for use in standard logging.
  """
  if not isinstance(level, int):
    raise TypeError('Expect an int level, found {}'.format(type(level)))
  if level < ABSL_FATAL:
    level = ABSL_FATAL
  if level <= ABSL_DEBUG:
    return ABSL_TO_STANDARD[level]
  # Maps to vlog levels.
  return STANDARD_DEBUG - level + 1


def string_to_standard(level):
  """Converts a string level to standard logging level value.

  Args:
    level: str, case-insensitive 'debug', 'info', 'warn', 'error', 'fatal'.

  Returns:
    The corresponding integer level for use in standard logging.
  """
  # Also support warning as an alias to warn.
  if level.upper() == 'WARNING':
    level = 'WARN'
  return absl_to_standard(ABSL_NAMES.get(level.upper()))


def standard_to_absl(level):
  """Converts an integer level from the standard value to the absl value.

  Args:
    level: int, a Python standard logging level.

  Raises:
    TypeError: Raised when level is not an integer.

  Returns:
    The corresponding integer level for use in absl logging.
  """
  if not isinstance(level, int):
    raise TypeError('Expect an int level, found {}'.format(type(level)))
  if level < 0:
    level = 0
  if level < STANDARD_DEBUG:
    # Maps to vlog levels.
    return STANDARD_DEBUG - level + 1
  elif level < STANDARD_INFO:
    return ABSL_DEBUG
  elif level < STANDARD_WARNING:
    return ABSL_INFO
  elif level < STANDARD_ERROR:
    return ABSL_WARN
  elif level < STANDARD_CRITICAL:
    return ABSL_ERROR
  else:
    return ABSL_FATAL


def standard_to_cpp(level):
  """Converts an integer level from the standard value to the cpp value.

  Args:
    level: int, a Python standard logging level.

  Raises:
    TypeError: Raised when level is not an integer.

  Returns:
    The corresponding integer level for use in cpp logging.
  """
  return absl_to_cpp(standard_to_absl(level))
