from mako.template import Template
from mako.lookup import TemplateLookup
from mako import lookup
import shutil, unittest, os, time
from test.util import result_lines
from test import TemplateTest, template_base, module_base
from test import eq_

try:
    import beaker
    import beaker.cache
except:
    from nose import SkipTest
    raise SkipTest("Beaker is required for these tests.")

from mako.cache import register_plugin, CacheImpl

class MockCacheImpl(CacheImpl):
    realcacheimpl = None

    def __init__(self, cache):
        self.cache = cache
        use_beaker = self.cache.\
                    template.cache_args.\
                    get('use_beaker', True)
        if use_beaker:
            self.realcacheimpl = cache._load_impl("beaker")

    def get_or_create(self, key, creation_function, **kw):
        self.key = key
        self.kwargs = kw.copy()
        if self.realcacheimpl:
            return self.realcacheimpl.\
                    get_or_create(key, creation_function, **kw)
        else:
            return creation_function()

    def put(self, key, value, **kw):
        self.key = key
        self.kwargs = kw.copy()
        if self.realcacheimpl:
            self.realcacheimpl.put(key, value, **kw)

    def get(self, key, **kw):
        self.key = key
        self.kwargs = kw.copy()
        if self.realcacheimpl:
            return self.realcacheimpl.get(key, **kw)

    def invalidate(self, key, **kw):
        self.key = key
        self.kwargs = kw.copy()
        if self.realcacheimpl:
            self.realcacheimpl.invalidate(key, **kw)


register_plugin("mock", __name__, "MockCacheImpl")

class BeakerCacheTest(TemplateTest):
    def _regions(self):
        return beaker.cache.CacheManager(
            cache_regions = {
                'short':{
                    'expire':1,
                    'type':'memory'
                },
                'long':{
                    'expire':60,
                    'type':'memory'
                }
            }
        )

    def test_region(self):
        t = Template("""
            <%block name="foo" cached="True" cache_region="short">
                short term ${x}
            </%block>
            <%block name="bar" cached="True" cache_region="long">
                long term ${x}
            </%block>
            <%block name="lala">
                none ${x}
            </%block>
        """, cache_args={"manager":self._regions()})

        r1 = result_lines(t.render(x=5))
        time.sleep(2)
        r2 = result_lines(t.render(x=6))
        r3 = result_lines(t.render(x=7))
        eq_(r1, ["short term 5", "long term 5", "none 5"])
        eq_(r2, ["short term 6", "long term 5", "none 6"])
        eq_(r3, ["short term 6", "long term 5", "none 7"])

class CacheTest(TemplateTest):
    def _install_mock_cache(self, template):
        template.cache_impl = 'mock'
        return template.cache.impl

    def test_def(self):
        t = Template("""
        <%!
            callcount = [0]
        %>
        <%def name="foo()" cached="True">
            this is foo
            <%
            callcount[0] += 1
            %>
        </%def>

        ${foo()}
        ${foo()}
        ${foo()}
        callcount: ${callcount}
""")
        m = self._install_mock_cache(t)
        assert result_lines(t.render()) == [
            'this is foo',
            'this is foo',
            'this is foo',
            'callcount: [1]',
        ]
        assert m.kwargs == {}

    def test_cache_enable(self):
        t = Template("""
            <%!
                callcount = [0]
            %>
            <%def name="foo()" cached="True">
                <% callcount[0] += 1 %>
            </%def>
            ${foo()}
            ${foo()}
            callcount: ${callcount}
        """, cache_enabled=False)
        m = self._install_mock_cache(t)

        eq_(t.render().strip(), "callcount: [2]")

    def test_nested_def(self):
        t = Template("""
        <%!
            callcount = [0]
        %>
        <%def name="foo()">
            <%def name="bar()" cached="True">
                this is foo
                <%
                callcount[0] += 1
                %>
            </%def>
            ${bar()}
        </%def>

        ${foo()}
        ${foo()}
        ${foo()}
        callcount: ${callcount}
""")
        m = self._install_mock_cache(t)
        assert result_lines(t.render()) == [
            'this is foo',
            'this is foo',
            'this is foo',
            'callcount: [1]',
        ]
        assert m.kwargs == {}

    def test_page(self):
        t = Template("""
        <%!
            callcount = [0]
        %>
        <%page cached="True"/>
        this is foo
        <%
        callcount[0] += 1
        %>
        callcount: ${callcount}
""")
        m = self._install_mock_cache(t)
        t.render()
        t.render()
        assert result_lines(t.render()) == [
            "this is foo",
            "callcount: [1]"
        ]
        assert m.kwargs == {}

    def test_dynamic_key_with_context(self):
        t = Template("""
            <%block name="foo" cached="True" cache_key="${mykey}">
                some block
            </%block>
        """)
        m = self._install_mock_cache(t)
        t.render(mykey="thekey")
        t.render(mykey="thekey")
        eq_(
            result_lines(t.render(mykey="thekey")),
            ["some block"]
        )
        eq_(m.key, "thekey")

        t = Template("""
            <%def name="foo()" cached="True" cache_key="${mykey}">
                some def
            </%def>
            ${foo()}
        """)
        m = self._install_mock_cache(t)
        t.render(mykey="thekey")
        t.render(mykey="thekey")
        eq_(
            result_lines(t.render(mykey="thekey")),
            ["some def"]
        )
        eq_(m.key, "thekey")


    def test_dynamic_key_with_funcargs(self):
        t = Template("""
            <%def name="foo(num=5)" cached="True" cache_key="foo_${str(num)}">
             hi
            </%def>

            ${foo()}
        """)
        m = self._install_mock_cache(t)
        t.render()
        t.render()
        assert result_lines(t.render()) == ['hi']
        assert m.key == "foo_5"

        t = Template("""
            <%def name="foo(*args, **kwargs)" cached="True" cache_key="foo_${kwargs['bar']}">
             hi
            </%def>

            ${foo(1, 2, bar='lala')}
        """)
        m = self._install_mock_cache(t)
        t.render()
        assert result_lines(t.render()) == ['hi']
        assert m.key == "foo_lala"

        t = Template('''
        <%page args="bar='hi'" cache_key="foo_${bar}" cached="True"/>
         hi
        ''')
        m = self._install_mock_cache(t)
        t.render()
        assert result_lines(t.render()) == ['hi']
        assert m.key == "foo_hi"


    def test_dynamic_key_with_imports(self):
        lookup = TemplateLookup()
        lookup.put_string("foo.html", """
        <%!
            callcount = [0]
        %>
        <%namespace file="ns.html" import="*"/>
        <%page cached="True" cache_key="${foo}"/>
        this is foo
        <%
        callcount[0] += 1
        %>
        callcount: ${callcount}
""")
        lookup.put_string("ns.html", """""")
        t = lookup.get_template("foo.html")
        m = self._install_mock_cache(t)
        t.render(foo='somekey')
        t.render(foo='somekey')
        assert result_lines(t.render(foo='somekey')) == [
            "this is foo",
            "callcount: [1]"
        ]
        assert m.kwargs == {}

    def test_fileargs_implicit(self):
        l = lookup.TemplateLookup(module_directory=module_base)
        l.put_string("test","""
                <%!
                    callcount = [0]
                %>
                <%def name="foo()" cached="True" cache_type='dbm'>
                    this is foo
                    <%
                    callcount[0] += 1
                    %>
                </%def>

                ${foo()}
                ${foo()}
                ${foo()}
                callcount: ${callcount}
        """)

        m = self._install_mock_cache(l.get_template('test'))
        assert result_lines(l.get_template('test').render()) == [
            'this is foo',
            'this is foo',
            'this is foo',
            'callcount: [1]',
        ]
        eq_(m.kwargs, {'type':'dbm'})

    def test_fileargs_deftag(self):
        t = Template("""
        <%%!
            callcount = [0]
        %%>
        <%%def name="foo()" cached="True" cache_type='file' cache_dir='%s'>
            this is foo
            <%%
            callcount[0] += 1
            %%>
        </%%def>

        ${foo()}
        ${foo()}
        ${foo()}
        callcount: ${callcount}
""" % module_base)
        m = self._install_mock_cache(t)
        assert result_lines(t.render()) == [
            'this is foo',
            'this is foo',
            'this is foo',
            'callcount: [1]',
        ]
        assert m.kwargs == {'type':'file','dir':module_base}

    def test_fileargs_pagetag(self):
        t = Template("""
        <%%page cache_dir='%s' cache_type='dbm'/>
        <%%!
            callcount = [0]
        %%>
        <%%def name="foo()" cached="True">
            this is foo
            <%%
            callcount[0] += 1
            %%>
        </%%def>

        ${foo()}
        ${foo()}
        ${foo()}
        callcount: ${callcount}
""" % module_base)
        m = self._install_mock_cache(t)
        assert result_lines(t.render()) == [
            'this is foo',
            'this is foo',
            'this is foo',
            'callcount: [1]',
        ]
        eq_(m.kwargs, {'dir':module_base, 'type':'dbm'})

    def test_args_complete(self):
        t = Template("""
        <%%def name="foo()" cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'>
            this is foo
        </%%def>

        ${foo()}
""" % module_base)
        m = self._install_mock_cache(t)
        t.render()
        eq_(m.kwargs, {'dir':module_base, 'type':'file', 'timeout':30})

        t2 = Template("""
        <%%page cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'/>
        hi
        """ % module_base)
        m = self._install_mock_cache(t2)
        t2.render()
        eq_(m.kwargs, {'dir':module_base, 'type':'file', 'timeout':30})

    def test_fileargs_lookup(self):
        l = lookup.TemplateLookup(cache_dir=module_base, cache_type='file')
        l.put_string("test","""
                <%!
                    callcount = [0]
                %>
                <%def name="foo()" cached="True">
                    this is foo
                    <%
                    callcount[0] += 1
                    %>
                </%def>

                ${foo()}
                ${foo()}
                ${foo()}
                callcount: ${callcount}
        """)

        t = l.get_template('test')
        m = self._install_mock_cache(t)
        assert result_lines(l.get_template('test').render()) == [
            'this is foo',
            'this is foo',
            'this is foo',
            'callcount: [1]',
        ]
        eq_(m.kwargs, {'dir':module_base, 'type':'file'})

    def test_buffered(self):
        t = Template("""
        <%!
            def a(text):
                return "this is a " + text.strip()
        %>
        ${foo()}
        ${foo()}
        <%def name="foo()" cached="True" buffered="True">
            this is a test
        </%def>
        """, buffer_filters=["a"])
        assert result_lines(t.render()) == ["this is a this is a test", "this is a this is a test"]

    def test_load_from_expired(self):
        """test that the cache callable can be called safely after the
        originating template has completed rendering.

        """
        t = Template("""
        ${foo()}
        <%def name="foo()" cached="True" cache_timeout="2">
            foo
        </%def>
        """)

        x1 = t.render()
        time.sleep(3)
        x2 = t.render()
        assert x1.strip() == x2.strip() == "foo"

    def test_cache_uses_current_context(self):
        t = Template("""
        ${foo()}
        <%def name="foo()" cached="True" cache_timeout="2">
            foo: ${x}
        </%def>
        """)

        x1 = t.render(x=1)
        time.sleep(3)
        x2 = t.render(x=2)
        eq_(x1.strip(), "foo: 1")
        eq_(x2.strip(), "foo: 2")

    def test_namespace_access(self):
        t = Template("""
            <%def name="foo(x)" cached="True">
                foo: ${x}
            </%def>

            <%
                foo(1)
                foo(2)
                local.cache.invalidate_def('foo')
                foo(3)
                foo(4)
            %>
        """)
        assert result_lines(t.render()) == ['foo: 1', 'foo: 1', 'foo: 3', 'foo: 3']

    def test_lookup(self):
        l = TemplateLookup(cache_impl='mock')
        l.put_string("x", """
            <%page cached="True" />
            ${y}
        """)
        t = l.get_template("x")
        assert result_lines(t.render(y=5)) == ["5"]
        assert result_lines(t.render(y=7)) == ["5"]
        assert isinstance(t.cache.impl, MockCacheImpl)

    def test_invalidate(self):
        t = Template("""
            <%%def name="foo()" cached="True">
                foo: ${x}
            </%%def>

            <%%def name="bar()" cached="True" cache_type='dbm' cache_dir='%s'>
                bar: ${x}
            </%%def>
            ${foo()} ${bar()}
        """ % module_base)
        assert result_lines(t.render(x=1)) == ["foo: 1", "bar: 1"]
        assert result_lines(t.render(x=2)) == ["foo: 1", "bar: 1"]
        t.cache.invalidate_def('foo')
        assert result_lines(t.render(x=3)) == ["foo: 3", "bar: 1"]
        t.cache.invalidate_def('bar')
        assert result_lines(t.render(x=4)) == ["foo: 3", "bar: 4"]

        t = Template("""
            <%%page cached="True" cache_type="dbm" cache_dir="%s"/>

            page: ${x}
        """ % module_base)
        assert result_lines(t.render(x=1)) == ["page: 1"]
        assert result_lines(t.render(x=2)) == ["page: 1"]
        t.cache.invalidate_body()
        assert result_lines(t.render(x=3)) == ["page: 3"]
        assert result_lines(t.render(x=4)) == ["page: 3"]

    def test_custom_args_def(self):
        t = Template("""
            <%def name="foo()" cached="True" cache_region="myregion"
                    cache_timeout="50" cache_foo="foob">
            </%def>
            ${foo()}
        """, cache_args={'use_beaker':False})
        m = self._install_mock_cache(t)
        t.render()
        eq_(m.kwargs, {'use_beaker':False,'region':'myregion', 'timeout':50, 'foo':'foob'})

    def test_custom_args_block(self):
        t = Template("""
            <%block name="foo" cached="True" cache_region="myregion"
                    cache_timeout="50" cache_foo="foob">
            </%block>
        """, cache_args={'use_beaker':False})
        m = self._install_mock_cache(t)
        t.render()
        eq_(m.kwargs, {'use_beaker':False, 'region':'myregion', 'timeout':50, 'foo':'foob'})

    def test_custom_args_page(self):
        t = Template("""
            <%page cached="True" cache_region="myregion"
                    cache_timeout="50" cache_foo="foob"/>
        """, cache_args={'use_beaker':False})
        m = self._install_mock_cache(t)
        t.render()
        eq_(m.kwargs, {'use_beaker':False, 'region':'myregion', 'timeout':50, 'foo':'foob'})

    def test_pass_context(self):
        t = Template("""
            <%page cached="True"/>
        """)
        m = self._install_mock_cache(t)
        t.render()
        assert 'context' not in m.kwargs

        m.pass_context = True
        t.render(x="bar")
        assert 'context' in m.kwargs
        assert m.kwargs['context'].get('x') == 'bar'

