"""
The bearlib is an optional library designed to ease the task of any Bear. Just
as the rest of coala the bearlib is designed to be as easy to use as possible
while offering the best possible flexibility.
"""

from coalib.settings.FunctionMetadata import FunctionMetadata


def deprecate_settings(**depr_args):
    """
     The purpose of this decorator is to allow passing old settings names to
     bears due to the heavy changes in their names.

     >>> @deprecate_settings(new='old')
     ... def run(new):
     ...     print(new)

     Now we can simply call the bear with the deprecated setting, we'll get a
     warning - but it still works!

     >>> run(old="Hello world!")
     The setting `old` is deprecated. Please use `new` instead.
     Hello world!
     >>> run(new="Hello world!")
     Hello world!

     This example represents the case where the old setting name needs to be
     modified to match the new one.

     >>> @deprecate_settings(new=('old', lambda a: a + 'coala!'))
     ... def func(new):
     ...     print(new)

     >>> func(old="Welcome to ")
     The setting `old` is deprecated. Please use `new` instead.
     Welcome to coala!
     >>> func(new='coala!')
     coala!

     The metadata for coala has been adjusted as well:

     >>> list(run.__metadata__.non_optional_params.keys())
     ['new']
     >>> list(run.__metadata__.optional_params.keys())
     ['old']

     You cannot deprecate an already deprecated setting. Don't try. It will
     introduce nondeterministic errors to your program.

     :param depr_args: A dictionary of settings as keys and their deprecated
                       names as values.
    """
    def _deprecate_decorator(func):

        def wrapping_function(*args, **kwargs):
            for arg, depr_arg_and_modifier in depr_args.items():
                deprecated_arg, _func = (
                    depr_arg_and_modifier
                    if isinstance(depr_arg_and_modifier, tuple)
                    else (depr_arg_and_modifier, lambda x: x))
                if deprecated_arg in kwargs and arg not in kwargs:
                    print("The setting `{}` is deprecated. Please use `{}` "
                          "instead.".format(deprecated_arg, arg))
                    kwargs[arg] = _func.__call__(kwargs[deprecated_arg])
                    del kwargs[deprecated_arg]
            return func(*args, **kwargs)

        new_metadata = FunctionMetadata.from_function(func)
        for arg, depr_arg_and_modifier in depr_args.items():
            deprecated_arg = (depr_arg_and_modifier[0]
                              if isinstance(depr_arg_and_modifier, tuple)
                              else depr_arg_and_modifier)
            new_metadata.add_alias(arg, deprecated_arg)
        wrapping_function.__metadata__ = new_metadata

        return wrapping_function

    return _deprecate_decorator

@@ -1203,16 +1203,596 @@
 coala!%0A%0A
+     This example represents the case where the old and new settings are%0A     provided to the function.%0A%0A     %3E%3E%3E @deprecate_settings(new='old')%0A     ... def run(new):%0A     ...     print(new)%0A     %3E%3E%3E run(old=%22Hello!%22, new='coala is always written with lowercase %60c%60.')%0A     The setting %60old%60 is deprecated. Please use %60new%60 instead.%0A     The value of %60old%60 and %60new%60 are conflicting. %60new%60 will be used instead.%0A     coala is always written with lowercase %60c%60.%0A     %3E%3E%3E run(old='Hello!', new='Hello!')%0A     The setting %60old%60 is deprecated. Please use %60new%60 instead.%0A     Hello!%0A%0A
      The
@@ -1838,16 +1838,16 @@
 s well:%0A
-
 %0A     %3E%3E
@@ -2640,30 +2640,8 @@
  in 
-kwargs and arg not in 
 kwar
@@ -2811,19 +2811,22 @@
     
-kwargs%5Barg%5D
+depr_arg_value
  = _
@@ -2863,16 +2863,372 @@
 d_arg%5D)%0A
+                    if arg in kwargs and depr_arg_value != kwargs%5Barg%5D:%0A                        print('The value of %60%7B%7D%60 and %60%7B%7D%60 are conflicting.'%0A                              ' %60%7B%7D%60 will be used instead.'.format(%0A                                  deprecated_arg, arg, arg))%0A                    else:%0A                        kwargs%5Barg%5D = depr_arg_value%0A
         

Allow using both deprecated and new setting