import re
import sys
import inspect
import warnings
from functools import wraps
from types import MethodType as MethodType
from collections import namedtuple

try:
    from collections import OrderedDict as MaybeOrderedDict
except ImportError:
    MaybeOrderedDict = dict

from unittest import TestCase

try:
    from unittest import SkipTest
except ImportError:
    class SkipTest(Exception):
        pass

PY3 = sys.version_info[0] == 3
PY2 = sys.version_info[0] == 2


if PY3:
    # Python 3 doesn't have an InstanceType, so just use a dummy type.
    class InstanceType():
        pass
    lzip = lambda *a: list(zip(*a))
    text_type = str
    string_types = str,
    bytes_type = bytes
    def make_method(func, instance, type):
        if instance is None:
            return func
        return MethodType(func, instance)
else:
    from types import InstanceType
    lzip = zip
    text_type = unicode
    bytes_type = str
    string_types = basestring,
    def make_method(func, instance, type):
        return MethodType(func, instance, type)

CompatArgSpec = namedtuple("CompatArgSpec", "args varargs keywords defaults")
def getargspec(func):
    if PY2:
        return CompatArgSpec(*inspect.getargspec(func))
    args = inspect.getfullargspec(func)
    if args.kwonlyargs:
        raise TypeError((
            "parameterized does not (yet) support functions with keyword "
            "only arguments, but %r has keyword only arguments. "
            "Please open an issue with your usecase if this affects you: "
            "https://github.com/wolever/parameterized/issues/new"
        ) %(func, ))
    return CompatArgSpec(*args[:4])

_param = namedtuple("param", "args kwargs")

def skip_on_empty_helper(*a, **kw):
    raise SkipTest("parameterized input is empty")

def reapply_patches_if_need(func):

    def dummy_wrapper(orgfunc):
        @wraps(orgfunc)
        def dummy_func(*args, **kwargs):
            return orgfunc(*args, **kwargs)
        return dummy_func

    if hasattr(func, 'patchings'):
        func = dummy_wrapper(func)
        tmp_patchings = func.patchings
        delattr(func, 'patchings')
        for patch_obj in tmp_patchings:
            func = patch_obj.decorate_callable(func)
    return func

def delete_patches_if_need(func):
    if hasattr(func, 'patchings'):
        func.patchings[:] = []


class param(_param):
    """ Represents a single parameter to a test case.

        For example::

            >>> p = param("foo", bar=16)
            >>> p
            param("foo", bar=16)
            >>> p.args
            ('foo', )
            >>> p.kwargs
            {'bar': 16}

        Intended to be used as an argument to ``@parameterized``::

            @parameterized([
                param("foo", bar=16),
            ])
            def test_stuff(foo, bar=16):
                pass
        """

    def __new__(cls, *args , **kwargs):
        return _param.__new__(cls, args, kwargs)

    @classmethod
    def explicit(cls, args=None, kwargs=None):
        """ Creates a ``param`` by explicitly specifying ``args`` and
            ``kwargs``::

                >>> param.explicit([1,2,3])
                param(*(1, 2, 3))
                >>> param.explicit(kwargs={"foo": 42})
                param(*(), **{"foo": "42"})
            """
        args = args or ()
        kwargs = kwargs or {}
        return cls(*args, **kwargs)

    @classmethod
    def from_decorator(cls, args):
        """ Returns an instance of ``param()`` for ``@parameterized`` argument
            ``args``::

                >>> param.from_decorator((42, ))
                param(args=(42, ), kwargs={})
                >>> param.from_decorator("foo")
                param(args=("foo", ), kwargs={})
            """
        if isinstance(args, param):
            return args
        elif isinstance(args, string_types):
            args = (args, )
        try:
            return cls(*args)
        except TypeError as e:
            if "after * must be" not in str(e):
                raise
            raise TypeError(
                "Parameters must be tuples, but %r is not (hint: use '(%r, )')"
                %(args, args),
            )

    def __repr__(self):
        return "param(*%r, **%r)" %self


class QuietOrderedDict(MaybeOrderedDict):
    """ When OrderedDict is available, use it to make sure that the kwargs in
        doc strings are consistently ordered. """
    __str__ = dict.__str__
    __repr__ = dict.__repr__


def parameterized_argument_value_pairs(func, p):
    """Return tuples of parameterized arguments and their values.

        This is useful if you are writing your own doc_func
        function and need to know the values for each parameter name::

            >>> def func(a, foo=None, bar=42, **kwargs): pass
            >>> p = param(1, foo=7, extra=99)
            >>> parameterized_argument_value_pairs(func, p)
            [("a", 1), ("foo", 7), ("bar", 42), ("**kwargs", {"extra": 99})]

        If the function's first argument is named ``self`` then it will be
        ignored::

            >>> def func(self, a): pass
            >>> p = param(1)
            >>> parameterized_argument_value_pairs(func, p)
            [("a", 1)]

        Additionally, empty ``*args`` or ``**kwargs`` will be ignored::

            >>> def func(foo, *args): pass
            >>> p = param(1)
            >>> parameterized_argument_value_pairs(func, p)
            [("foo", 1)]
            >>> p = param(1, 16)
            >>> parameterized_argument_value_pairs(func, p)
            [("foo", 1), ("*args", (16, ))]
    """
    argspec = getargspec(func)
    arg_offset = 1 if argspec.args[:1] == ["self"] else 0

    named_args = argspec.args[arg_offset:]

    result = lzip(named_args, p.args)
    named_args = argspec.args[len(result) + arg_offset:]
    varargs = p.args[len(result):]

    result.extend([
        (name, p.kwargs.get(name, default))
        for (name, default)
        in zip(named_args, argspec.defaults or [])
    ])

    seen_arg_names = set([ n for (n, _) in result ])
    keywords = QuietOrderedDict(sorted([
        (name, p.kwargs[name])
        for name in p.kwargs
        if name not in seen_arg_names
    ]))

    if varargs:
        result.append(("*%s" %(argspec.varargs, ), tuple(varargs)))

    if keywords:
        result.append(("**%s" %(argspec.keywords, ), keywords))

    return result

def short_repr(x, n=64):
    """ A shortened repr of ``x`` which is guaranteed to be ``unicode``::

            >>> short_repr("foo")
            u"foo"
            >>> short_repr("123456789", n=4)
            u"12...89"
    """

    x_repr = repr(x)
    if isinstance(x_repr, bytes_type):
        try:
            x_repr = text_type(x_repr, "utf-8")
        except UnicodeDecodeError:
            x_repr = text_type(x_repr, "latin1")
    if len(x_repr) > n:
        x_repr = x_repr[:n//2] + "..." + x_repr[len(x_repr) - n//2:]
    return x_repr

def default_doc_func(func, num, p):
    if func.__doc__ is None:
        return None

    all_args_with_values = parameterized_argument_value_pairs(func, p)

    # Assumes that the function passed is a bound method.
    descs = ["%s=%s" %(n, short_repr(v)) for n, v in all_args_with_values]

    # The documentation might be a multiline string, so split it
    # and just work with the first string, ignoring the period
    # at the end if there is one.
    first, nl, rest = func.__doc__.lstrip().partition("\n")
    suffix = ""
    if first.endswith("."):
        suffix = "."
        first = first[:-1]
    args = "%s[with %s]" %(len(first) and " " or "", ", ".join(descs))
    return "".join([first.rstrip(), args, suffix, nl, rest])

def default_name_func(func, num, p):
    base_name = func.__name__
    name_suffix = "_%s" %(num, )
    if len(p.args) > 0 and isinstance(p.args[0], string_types):
        name_suffix += "_" + parameterized.to_safe_name(p.args[0])
    return base_name + name_suffix


_test_runner_override = None
_test_runner_guess = False
_test_runners = set(["unittest", "unittest2", "nose", "nose2", "pytest"])
_test_runner_aliases = {
    "_pytest": "pytest",
}

def set_test_runner(name):
    global _test_runner_override
    if name not in _test_runners:
        raise TypeError(
            "Invalid test runner: %r (must be one of: %s)"
            %(name, ", ".join(_test_runners)),
        )
    _test_runner_override = name

def detect_runner():
    """ Guess which test runner we're using by traversing the stack and looking
        for the first matching module. This *should* be reasonably safe, as
        it's done during test disocvery where the test runner should be the
        stack frame immediately outside. """
    if _test_runner_override is not None:
        return _test_runner_override
    global _test_runner_guess
    if _test_runner_guess is False:
        stack = inspect.stack()
        for record in reversed(stack):
            frame = record[0]
            module = frame.f_globals.get("__name__").partition(".")[0]
            if module in _test_runner_aliases:
                module = _test_runner_aliases[module]
            if module in _test_runners:
                _test_runner_guess = module
                break
            if record[1].endswith("python2.6/unittest.py"):
                _test_runner_guess = "unittest"
                break
        else:
            _test_runner_guess = None
    return _test_runner_guess


class parameterized(object):
    """ Parameterize a test case::

            class TestInt(object):
                @parameterized([
                    ("A", 10),
                    ("F", 15),
                    param("10", 42, base=42)
                ])
                def test_int(self, input, expected, base=16):
                    actual = int(input, base=base)
                    assert_equal(actual, expected)

            @parameterized([
                (2, 3, 5)
                (3, 5, 8),
            ])
            def test_add(a, b, expected):
                assert_equal(a + b, expected)
        """

    def __init__(self, input, doc_func=None, skip_on_empty=False):
        self.get_input = self.input_as_callable(input)
        self.doc_func = doc_func or default_doc_func
        self.skip_on_empty = skip_on_empty

    def __call__(self, test_func):
        self.assert_not_in_testcase_subclass()

        @wraps(test_func)
        def wrapper(test_self=None):
            test_cls = test_self and type(test_self)
            if test_self is not None:
                if issubclass(test_cls, InstanceType):
                    raise TypeError((
                        "@parameterized can't be used with old-style classes, but "
                        "%r has an old-style class. Consider using a new-style "
                        "class, or '@parameterized.expand' "
                        "(see http://stackoverflow.com/q/54867/71522 for more "
                        "information on old-style classes)."
                    ) %(test_self, ))

            original_doc = wrapper.__doc__
            for num, args in enumerate(wrapper.parameterized_input):
                p = param.from_decorator(args)
                unbound_func, nose_tuple = self.param_as_nose_tuple(test_self, test_func, num, p)
                try:
                    wrapper.__doc__ = nose_tuple[0].__doc__
                    # Nose uses `getattr(instance, test_func.__name__)` to get
                    # a method bound to the test instance (as opposed to a
                    # method bound to the instance of the class created when
                    # tests were being enumerated). Set a value here to make
                    # sure nose can get the correct test method.
                    if test_self is not None:
                        setattr(test_cls, test_func.__name__, unbound_func)
                    yield nose_tuple
                finally:
                    if test_self is not None:
                        delattr(test_cls, test_func.__name__)
                    wrapper.__doc__ = original_doc

        input = self.get_input()
        if not input:
            if not self.skip_on_empty:
                raise ValueError(
                    "Parameters iterable is empty (hint: use "
                    "`parameterized([], skip_on_empty=True)` to skip "
                    "this test when the input is empty)"
                )
            wrapper = wraps(test_func)(lambda: skip_on_empty_helper())

        wrapper.parameterized_input = input
        wrapper.parameterized_func = test_func
        test_func.__name__ = "_parameterized_original_%s" %(test_func.__name__, )

        return wrapper

    def param_as_nose_tuple(self, test_self, func, num, p):
        nose_func = wraps(func)(lambda *args: func(*args[:-1], **args[-1]))
        nose_func.__doc__ = self.doc_func(func, num, p)
        # Track the unbound function because we need to setattr the unbound
        # function onto the class for nose to work (see comments above), and
        # Python 3 doesn't let us pull the function out of a bound method.
        unbound_func = nose_func
        if test_self is not None:
            # Under nose on Py2 we need to return an unbound method to make
            # sure that the `self` in the method is properly shared with the
            # `self` used in `setUp` and `tearDown`. But only there. Everyone
            # else needs a bound method.
            func_self = (
                None if PY2 and detect_runner() == "nose" else
                test_self
            )
            nose_func = make_method(nose_func, func_self, type(test_self))
        return unbound_func, (nose_func, ) + p.args + (p.kwargs or {}, )

    def assert_not_in_testcase_subclass(self):
        parent_classes = self._terrible_magic_get_defining_classes()
        if any(issubclass(cls, TestCase) for cls in parent_classes):
            raise Exception("Warning: '@parameterized' tests won't work "
                            "inside subclasses of 'TestCase' - use "
                            "'@parameterized.expand' instead.")

    def _terrible_magic_get_defining_classes(self):
        """ Returns the set of parent classes of the class currently being defined.
            Will likely only work if called from the ``parameterized`` decorator.
            This function is entirely @brandon_rhodes's fault, as he suggested
            the implementation: http://stackoverflow.com/a/8793684/71522
            """
        stack = inspect.stack()
        if len(stack) <= 4:
            return []
        frame = stack[4]
        code_context = frame[4] and frame[4][0].strip()
        if not (code_context and code_context.startswith("class ")):
            return []
        _, _, parents = code_context.partition("(")
        parents, _, _ = parents.partition(")")
        return eval("[" + parents + "]", frame[0].f_globals, frame[0].f_locals)

    @classmethod
    def input_as_callable(cls, input):
        if callable(input):
            return lambda: cls.check_input_values(input())
        input_values = cls.check_input_values(input)
        return lambda: input_values

    @classmethod
    def check_input_values(cls, input_values):
        # Explicitly convery non-list inputs to a list so that:
        # 1. A helpful exception will be raised if they aren't iterable, and
        # 2. Generators are unwrapped exactly once (otherwise `nosetests
        #    --processes=n` has issues; see:
        #    https://github.com/wolever/nose-parameterized/pull/31)
        if not isinstance(input_values, list):
            input_values = list(input_values)
        return [ param.from_decorator(p) for p in input_values ]

    @classmethod
    def expand(cls, input, name_func=None, doc_func=None, skip_on_empty=False,
               **legacy):
        """ A "brute force" method of parameterizing test cases. Creates new
            test cases and injects them into the namespace that the wrapped
            function is being defined in. Useful for parameterizing tests in
            subclasses of 'UnitTest', where Nose test generators don't work.

            >>> @parameterized.expand([("foo", 1, 2)])
            ... def test_add1(name, input, expected):
            ...     actual = add1(input)
            ...     assert_equal(actual, expected)
            ...
            >>> locals()
            ... 'test_add1_foo_0': <function ...> ...
            >>>
            """

        if "testcase_func_name" in legacy:
            warnings.warn("testcase_func_name= is deprecated; use name_func=",
                          DeprecationWarning, stacklevel=2)
            if not name_func:
                name_func = legacy["testcase_func_name"]

        if "testcase_func_doc" in legacy:
            warnings.warn("testcase_func_doc= is deprecated; use doc_func=",
                          DeprecationWarning, stacklevel=2)
            if not doc_func:
                doc_func = legacy["testcase_func_doc"]

        doc_func = doc_func or default_doc_func
        name_func = name_func or default_name_func

        def parameterized_expand_wrapper(f, instance=None):
            stack = inspect.stack()
            frame = stack[1]
            frame_locals = frame[0].f_locals

            paramters = cls.input_as_callable(input)()

            if not paramters:
                if not skip_on_empty:
                    raise ValueError(
                        "Parameters iterable is empty (hint: use "
                        "`parameterized.expand([], skip_on_empty=True)` to skip "
                        "this test when the input is empty)"
                    )
                return wraps(f)(lambda: skip_on_empty_helper())

            digits = len(str(len(paramters) - 1))
            for num, p in enumerate(paramters):
                name = name_func(f, "{num:0>{digits}}".format(digits=digits, num=num), p)
                # If the original function has patches applied by 'mock.patch',
                # re-construct all patches on the just former decoration layer
                # of param_as_standalone_func so as not to share
                # patch objects between new functions
                nf = reapply_patches_if_need(f)
                frame_locals[name] = cls.param_as_standalone_func(p, nf, name)
                frame_locals[name].__doc__ = doc_func(f, num, p)

            # Delete original patches to prevent new function from evaluating
            # original patching object as well as re-constructed patches.
            delete_patches_if_need(f)

            f.__test__ = False
        return parameterized_expand_wrapper

    @classmethod
    def param_as_standalone_func(cls, p, func, name):
        @wraps(func)
        def standalone_func(*a):
            return func(*(a + p.args), **p.kwargs)
        standalone_func.__name__ = name

        # place_as is used by py.test to determine what source file should be
        # used for this test.
        standalone_func.place_as = func

        # Remove __wrapped__ because py.test will try to look at __wrapped__
        # to determine which parameters should be used with this test case,
        # and obviously we don't need it to do any parameterization.
        try:
            del standalone_func.__wrapped__
        except AttributeError:
            pass
        return standalone_func

    @classmethod
    def to_safe_name(cls, s):
        return str(re.sub("[^a-zA-Z0-9_]+", "_", s))


def parameterized_class(attrs, input_values=None):
    """ Parameterizes a test class by setting attributes on the class.

        Can be used in two ways:

        1) With a list of dictionaries containing attributes to override::

            @parameterized_class([
                { "username": "foo" },
                { "username": "bar", "access_level": 2 },
            ])
            class TestUserAccessLevel(TestCase):
                ...

        2) With a tuple of attributes, then a list of tuples of values:

            @parameterized_class(("username", "access_level"), [
                ("foo", 1),
                ("bar", 2)
            ])
            class TestUserAccessLevel(TestCase):
                ...

    """

    if isinstance(attrs, string_types):
        attrs = [attrs]

    input_dicts = (
        attrs if input_values is None else
        [dict(zip(attrs, vals)) for vals in input_values]
    )

    def decorator(base_class):
        test_class_module = sys.modules[base_class.__module__].__dict__
        for idx, input_dict in enumerate(input_dicts):
            test_class_dict = dict(base_class.__dict__)
            test_class_dict.update(input_dict)

            name_suffix = input_values and input_values[idx]
            if isinstance(name_suffix, (list, tuple)) and len(input_values) > 0:
                name_suffix = name_suffix[0]
            name_suffix = (
                "_%s" %(name_suffix, ) if isinstance(name_suffix, string_types) else
                ""
            )

            name = "%s_%s%s" %(
                base_class.__name__,
                idx,
                name_suffix,
            )

            test_class_module[name] = type(name, (base_class, ), test_class_dict)

        # We need to leave the base class in place (see issue #73), but if we
        # leave the test_ methods in place, the test runner will try to pick
        # them up and run them… which doesn't make sense, since no parameters
        # will have been applied.
        # Address this by iterating over the base class and remove all test
        # methods.
        for method_name in list(base_class.__dict__):
            if method_name.startswith("test_"):
                delattr(base_class, method_name)
        return base_class

    return decorator
