#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
#

"""Deprecated annotations.

Deprecated: Signifies that users are discouraged from using a public API
typically because a better alternative exists, and the current form might be
removed in a future version.

Usage:
For internal use only; no backwards-compatibility guarantees.

Annotations come in two flavors: deprecated and experimental

The 'deprecated' annotation requires a 'since" parameter to specify
what version deprecated it.
Both 'deprecated' and 'experimental' annotations can specify the
current recommended version to use by means of a 'current' parameter.

The following example illustrates how to annotate coexisting versions of the
same function 'multiply'.::

  def multiply(arg1, arg2):
    print(arg1, '*', arg2, '=', end=' ')
    return arg1*arg2

# This annotation marks 'old_multiply' as deprecated since 'v.1' and suggests
# using 'multiply' instead.::

  @deprecated(since='v.1', current='multiply')
  def old_multiply(arg1, arg2):
    result = 0
    for i in xrange(arg1):
        result += arg2
    print(arg1, '*', arg2, '(the old way)=', end=' ')
    return result

# Set a warning filter to control how often warnings are produced.::

  warnings.simplefilter("always")
  print(multiply(5, 6))
  print(old_multiply(5,6))
"""

# pytype: skip-file

import inspect
import warnings
from functools import partial
from functools import wraps


def _add_deprecation_notice_to_docstring(docstring, message):
  """Adds a deprecation notice to a docstring.

  Args:
    docstring: The original docstring (can be None or empty).
    message: The deprecation message to add.

  Returns:
    The modified docstring.
  """
  if docstring:
    return f"{docstring}\n\n.. deprecated:: {message}"
  else:
    return f".. deprecated:: {message}"


class BeamDeprecationWarning(DeprecationWarning):
  """Beam-specific deprecation warnings."""


# Don't ignore BeamDeprecationWarnings.
warnings.simplefilter('once', BeamDeprecationWarning)


class _WarningMessage:
  """Utility class for assembling the warning message."""
  def __init__(self, label, since, current, extra_message, custom_message):
    """Initialize message, leave only name as placeholder."""
    if custom_message is None:
      message = '%name% is ' + label
      if label == 'deprecated':
        message += ' since %s' % since
      message += '. Use %s instead.' % current if current else '.'
      if extra_message:
        message += ' ' + extra_message
    else:
      if label == 'deprecated' and '%since%' not in custom_message:
        raise TypeError(
            "Replacement string %since% not found on \
        custom message")
      emptyArg = lambda x: '' if x is None else x
      message = custom_message\
      .replace('%since%', emptyArg(since))\
      .replace('%current%', emptyArg(current))\
      .replace('%extra%', emptyArg(extra_message))
    self.label = label
    self.message = message

  def emit_warning(self, fnc_name):
    if self.label == 'deprecated':
      warning_type = BeamDeprecationWarning
    else:
      warning_type = FutureWarning
    warnings.warn(
        self.message.replace('%name%', fnc_name), warning_type, stacklevel=3)


def annotate(label, since, current, extra_message, custom_message=None):
  """Decorates an API with a deprecated or experimental annotation.

  Args:
    label: the kind of annotation ('deprecated' or 'experimental').
    since: the version that causes the annotation.
    current: the suggested replacement function.
    extra_message: an optional additional message.
    custom_message: if the default message does not suffice, the message
      can be changed using this argument. A string
      whit replacement tokens.
      A replecement string is were the previus args will
      be located on the custom message.
      The following replacement strings can be used:
      %name% -> API.__name__
      %since% -> since (Mandatory for the decapreted annotation)
      %current% -> current
      %extra% -> extra_message

  Returns:
    The decorator for the API.
  """
  warning_message = _WarningMessage(
      label=label,
      since=since,
      current=current,
      extra_message=extra_message,
      custom_message=custom_message)

  def _annotate(fnc):
    if inspect.isclass(fnc):
      # Wrapping class into function causes documentation rendering issue.
      # Patch class's __new__ method instead.
      old_new = fnc.__new__

      def wrapped_new(cls, *args, **kwargs):
        # Emit a warning when class instance is created.
        warning_message.emit_warning(fnc.__name__)
        if old_new is object.__new__:
          # object.__new__ takes no extra argument for python>=3
          return old_new(cls)
        return old_new(cls, *args, **kwargs)

      fnc.__new__ = staticmethod(wrapped_new)
      if label == 'deprecated':
        fnc.__doc__ = _add_deprecation_notice_to_docstring(
            fnc.__doc__,
            warning_message.message.replace('%name%', fnc.__name__))
      return fnc
    else:

      @wraps(fnc)
      def inner(*args, **kwargs):
        # Emit a warning when the function is called.
        warning_message.emit_warning(fnc.__name__)
        return fnc(*args, **kwargs)

      if label == 'deprecated':
        inner.__doc__ = _add_deprecation_notice_to_docstring(
            fnc.__doc__,
            warning_message.message.replace('%name%', fnc.__name__))
      return inner

  return _annotate


# Use partial application to customize each annotation.
# 'current' will be optional in both deprecated and experimental
# while 'since' will be mandatory for deprecated.
deprecated = partial(
    annotate, label='deprecated', current=None, extra_message=None)
