#
# 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


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)
      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)

      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)
