#!/usr/bin/env python
# -*- coding: utf-8 -*-

import warnings
import functools
import inspect
import sys


def usage(message, level=1):
    """Pour prévenir que ce que tu fais c'est mal et qu'il faut plus le faire comme ça.
       ``level`` permet de préciser de combien de crans il faut remonter
       pour afficher la ligne responsable de l'erreur"""
    warnings.resetwarnings()
    warnings.warn(message, category=DeprecationWarning, stacklevel=level + 1)

def deprecated(replace=None):
    '''This is a decorator which can be used to mark functions
    as deprecated. It will result in a warning being emitted
    when the function is used.'''
    
    warnings.resetwarnings()

    if replace == None:
        instead = ""
    elif isinstance(replace, str) or isinstance(replace, unicode):
        instead = " " + replace
    else:
        instead = " Use %s instead." % (replace.__name__,)
    
    def real_decorator(func):
        """Nested because a decorator with a parameter has to be coded this way"""
        @functools.wraps(func)
        def new_func(*args, **kwargs):
            warnings.warn_explicit(
                "Call to deprecated function %s.%s" % (func.__name__, instead),
                category=DeprecationWarning,
                filename=func.func_code.co_filename,
                lineno=func.func_code.co_firstlineno + 1
                )
            return func(*args, **kwargs)
        return new_func
    return real_decorator

def module(replace=None):
    """À appeler dans un module déprécié"""

    # On récupère le nom du module appelant la fonction
    frm = inspect.stack()[1]
    mod = inspect.getmodule(frm[0])
    if mod and mod.__name__ != '__main__':
        module_name = mod.__name__
    else:
        module_name = sys.argv[0]

    if replace == None:
        instead = ""
    elif isinstance(replace, str) or isinstance(replace, unicode):
        instead = " " + replace
    else:
        instead = " Use %s instead." % (replace.__name__,)

    usage("Call to deprecated module %s.%s" % (module_name, instead), level=3)

