from mako.template import Template
import unittest
import os
from mako.compat import py3k, py26, py33
from mako import compat
from mako.util import update_wrapper
import re
from mako.cache import CacheImpl, register_plugin

try:
    from nose import SkipTest
except ImportError:
    from unittest import SkipTest

import contextlib

template_base = os.path.join(os.path.dirname(__file__), 'templates')
module_base = os.path.join(template_base, 'modules')

class TemplateTest(unittest.TestCase):

    def _file_template(self, filename, **kw):
        filepath = self._file_path(filename)
        return Template(uri=filename, filename=filepath,
                            module_directory=module_base, **kw)

    def _file_path(self, filename):
        name, ext = os.path.splitext(filename)

        if py3k:
            py3k_path = os.path.join(template_base, name + "_py3k" + ext)
            if os.path.exists(py3k_path):
                return py3k_path

        return os.path.join(template_base, filename)

    def _do_file_test(self, filename, expected, filters=None,
                        unicode_=True, template_args=None, **kw):
        t1 = self._file_template(filename, **kw)
        self._do_test(t1, expected, filters=filters,
                        unicode_=unicode_, template_args=template_args)

    def _do_memory_test(self, source, expected, filters=None,
                        unicode_=True, template_args=None, **kw):
        t1 = Template(text=source, **kw)
        self._do_test(t1, expected, filters=filters,
                        unicode_=unicode_, template_args=template_args)

    def _do_test(self, template, expected, filters=None, template_args=None,
                                unicode_=True):
        if template_args is None:
            template_args = {}
        if unicode_:
            output = template.render_unicode(**template_args)
        else:
            output = template.render(**template_args)

        if filters:
            output = filters(output)
        eq_(output, expected)

def eq_(a, b, msg=None):
    """Assert a == b, with repr messaging on failure."""
    assert a == b, msg or "%r != %r" % (a, b)

def teardown():
    import shutil
    shutil.rmtree(module_base, True)

if py33:
    from unittest import mock
else:
    import mock

@contextlib.contextmanager
def raises(except_cls, message=None):
    try:
        yield
        success = False
    except except_cls as e:
        if message:
            assert re.search(message, compat.text_type(e), re.UNICODE), \
                            "%r !~ %s" % (message, e)
            print(compat.text_type(e).encode('utf-8'))
        success = True

    # assert outside the block so it works for AssertionError too !
    assert success, "Callable did not raise an exception"


def assert_raises(except_cls, callable_, *args, **kw):
    with raises(except_cls):
        return callable_(*args, **kw)

def assert_raises_message(except_cls, msg, callable_, *args, **kwargs):
    with raises(except_cls, msg):
        return callable_(*args, **kwargs)

def skip_if(predicate, reason=None):
    """Skip a test if predicate is true."""
    reason = reason or predicate.__name__

    def decorate(fn):
        fn_name = fn.__name__
        def maybe(*args, **kw):
            if predicate():
                msg = "'%s' skipped: %s" % (
                    fn_name, reason)
                raise SkipTest(msg)
            else:
                return fn(*args, **kw)
        return update_wrapper(maybe, fn)
    return decorate

def requires_python_3(fn):
    return skip_if(lambda: not py3k, "Requires Python 3.xx")(fn)

def requires_python_2(fn):
    return skip_if(lambda: py3k, "Requires Python 2.xx")(fn)

def requires_python_26_or_greater(fn):
    return skip_if(lambda: not py26, "Requires Python 2.6 or greater")(fn)

def requires_pygments_14(fn):
    try:
        import pygments
        version = pygments.__version__
    except:
        version = "0"
    return skip_if(lambda: version < "1.4", "Requires pygments 1.4 or greater")(fn)

def requires_no_pygments_exceptions(fn):
    def go(*arg, **kw):
        from mako import exceptions
        exceptions._install_fallback()
        try:
            return fn(*arg, **kw)
        finally:
            exceptions._install_highlighting()
    return update_wrapper(go, fn)

class PlainCacheImpl(CacheImpl):
    """Simple memory cache impl so that tests which
    use caching can run without beaker.  """

    def __init__(self, cache):
        self.cache = cache
        self.data = {}

    def get_or_create(self, key, creation_function, **kw):
        if key in self.data:
            return self.data[key]
        else:
            self.data[key] = data = creation_function(**kw)
            return data

    def put(self, key, value, **kw):
        self.data[key] = value

    def get(self, key, **kw):
        return self.data[key]

    def invalidate(self, key, **kw):
        del self.data[key]

register_plugin("plain", __name__, "PlainCacheImpl")
