# -*- coding:utf-8 -*-
"""
This module is pending deprecation as of Django 1.6 and will be removed in
version 1.8.

"""
from importlib import import_module
import json
import re
import unittest as real_unittest
import warnings

from django.apps import apps
from django.test import _doctest as doctest
from django.test import runner
from django.test.utils import compare_xml, strip_quotes
# django.utils.unittest is deprecated, but so is django.test.simple,
# and the latter will be removed before the former.
from django.utils import unittest
from django.utils.deprecation import RemovedInDjango18Warning
from django.utils.module_loading import module_has_submodule

__all__ = ('DjangoTestSuiteRunner',)

warnings.warn(
    "The django.test.simple module and DjangoTestSuiteRunner are deprecated; "
    "use django.test.runner.DiscoverRunner instead.",
    RemovedInDjango18Warning)

# The module name for tests outside models.py
TEST_MODULE = 'tests'


normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)
normalize_decimals = lambda s: re.sub(r"Decimal\('(\d+(\.\d*)?)'\)",
                                lambda m: "Decimal(\"%s\")" % m.groups()[0], s)


class OutputChecker(doctest.OutputChecker):
    def check_output(self, want, got, optionflags):
        """
        The entry method for doctest output checking. Defers to a sequence of
        child checkers
        """
        checks = (self.check_output_default,
                  self.check_output_numeric,
                  self.check_output_xml,
                  self.check_output_json)
        for check in checks:
            if check(want, got, optionflags):
                return True
        return False

    def check_output_default(self, want, got, optionflags):
        """
        The default comparator provided by doctest - not perfect, but good for
        most purposes
        """
        return doctest.OutputChecker.check_output(self, want, got, optionflags)

    def check_output_numeric(self, want, got, optionflags):
        """Doctest does an exact string comparison of output, which means that
        some numerically equivalent values aren't equal. This check normalizes
         * long integers (22L) so that they equal normal integers. (22)
         * Decimals so that they are comparable, regardless of the change
           made to __repr__ in Python 2.6.
        """
        return doctest.OutputChecker.check_output(self,
            normalize_decimals(normalize_long_ints(want)),
            normalize_decimals(normalize_long_ints(got)),
            optionflags)

    def check_output_xml(self, want, got, optionsflags):
        try:
            return compare_xml(want, got)
        except Exception:
            return False

    def check_output_json(self, want, got, optionsflags):
        """
        Tries to compare want and got as if they were JSON-encoded data
        """
        want, got = strip_quotes(want, got)
        try:
            want_json = json.loads(want)
            got_json = json.loads(got)
        except Exception: