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


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[:] = []


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

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

            parameters = cls.input_as_callable(input)()

            if not parameters:
                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(parameters) - 1))
            for num, p in enumerate(parameters):
                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, classname_func=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]
    )

    classname_func = classname_func or default_classname_func

    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 = classname_func(base_class, idx, input_dict)

            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


def get_classname_suffix(params_dict):
    if "name" in params_dict:
        return parameterized.to_safe_name(params_dict["name"])

    params_vals = (
        params_dict.values() if PY3 else
        (v for (_, v) in sorted(params_dict.items()))
    )
    return parameterized.to_safe_name(next((
        v for v in params_vals
        if isinstance(v, string_types)
    ), ""))


def default_classname_func(cls, num, params_dict):
    suffix = get_classname_suffix(params_dict)
    return "%s_%s%s" %(
        cls.__name__,
        num,
        suffix and "_" + suffix,
    )
