import random
import time
import unittest

try:
    range = xrange
except NameError: # pragma: NO COVER  (Python3)
    pass


class LRUCacheTests(unittest.TestCase):

    def _getTargetClass(self):
        from repoze.lru import LRUCache
        return LRUCache

    def check_cache_is_consistent(self, cache):
        #Return if cache is consistent, else raise fail test case.
        # cache.hand/maxpos/size
        self.assertTrue(cache.hand < len(cache.clock_keys))
        self.assertTrue(cache.hand >= 0)
        self.assertEqual(cache.maxpos, cache.size - 1)
        self.assertEqual(len(cache.clock_keys), cache.size)

        # lengths of data structures
        self.assertEqual(len(cache.clock_keys), len(cache.clock_refs))
        self.assertTrue(len(cache.data) <= len(cache.clock_refs))

        # For each item in cache.data
        #   1. pos must be a valid index
        #   2. clock_keys must point back to the entry
        for key, value in cache.data.items():
            pos, val = value
            self.assertTrue(
                    type(pos) == type(42) or
                    type(pos) == type(2 ** 128))
            self.assertTrue(pos >= 0)
            self.assertTrue(pos <= cache.maxpos)

            clock_key = cache.clock_keys[pos]
            self.assertTrue(clock_key is key)
            clock_ref = cache.clock_refs[pos]

        # All clock_refs must be True or False, nothing else.
        for clock_ref in cache.clock_refs:
            self.assertTrue(clock_ref is True or clock_ref is False)

    def _makeOne(self, size):
        return self._getTargetClass()(size)

    def test_size_lessthan_1(self):
        self.assertRaises(ValueError, self._makeOne, 0)

    def test_get(self):
        cache = self._makeOne(1)
        # Must support different types of keys
        self.assertEqual(cache.get("foo"), None)
        self.assertEqual(cache.get(42), None)
        self.assertEqual(cache.get(("foo", 42)), None)
        self.assertEqual(cache.get(None), None)
        self.assertEqual(cache.get(""), None)
        self.assertEqual(cache.get(object()), None)
        # Check if default value is used
        self.assertEqual(cache.get("foo", "bar"), "bar")
        self.assertEqual(cache.get("foo", default="bar"), "bar")

        self.check_cache_is_consistent(cache)

    def test_put(self):
        cache = self._makeOne(8)
        self.check_cache_is_consistent(cache)
        # Must support different types of keys
        cache.put("foo", "FOO")
        cache.put(42, "fortytwo")
        cache.put( ("foo", 42), "tuple_as_key")
        cache.put(None, "None_as_key")
        cache.put("", "empty_string_as_key")
        cache.put(3.141, "float_as_key")
        my_object = object()
        cache.put(my_object, "object_as_key")

        self.check_cache_is_consistent(cache)

        self.assertEqual(cache.get("foo"), "FOO")
        self.assertEqual(cache.get(42), "fortytwo")
        self.assertEqual(cache.get(("foo", 42), "fortytwo"), "tuple_as_key")
        self.assertEqual(cache.get(None), "None_as_key")
        self.assertEqual(cache.get(""), "empty_string_as_key")
        self.assertEqual(cache.get(3.141), "float_as_key")
        self.assertEqual(cache.get(my_object), "object_as_key")

        # put()ing again must overwrite
        cache.put(42, "fortytwo again")
        self.assertEqual(cache.get(42), "fortytwo again")

        self.check_cache_is_consistent(cache)

    def test_invalidate(self):
        cache = self._makeOne(3)
        cache.put("foo", "bar")
        cache.put("FOO", "BAR")

        cache.invalidate("foo")
        self.assertEqual(cache.get("foo"), None)
        self.assertEqual(cache.get("FOO"), "BAR")
        self.check_cache_is_consistent(cache)

        cache.invalidate("FOO")
        self.assertEqual(cache.get("foo"), None)
        self.assertEqual(cache.get("FOO"), None)
        self.assertEqual(cache.data, {})
        self.check_cache_is_consistent(cache)

        cache.put("foo", "bar")
        cache.invalidate("nonexistingkey")
        self.assertEqual(cache.get("foo"), "bar")
        self.assertEqual(cache.get("FOO"), None)
        self.check_cache_is_consistent(cache)

    def test_small_cache(self):
        #Cache of size 1 must work
        cache = self._makeOne(1)

        cache.put("foo", "bar")
        self.assertEqual(cache.get("foo"), "bar")
        self.check_cache_is_consistent(cache)

        cache.put("FOO", "BAR")
        self.assertEqual(cache.get("FOO"), "BAR")
        self.assertEqual(cache.get("foo"), None)
        self.check_cache_is_consistent(cache)

        # put() again
        cache.put("FOO", "BAR")
        self.assertEqual(cache.get("FOO"), "BAR")
        self.assertEqual(cache.get("foo"), None)
        self.check_cache_is_consistent(cache)

        # invalidate()
        cache.invalidate("FOO")
        self.check_cache_is_consistent(cache)
        self.assertEqual(cache.get("FOO"), None)
        self.assertEqual(cache.get("foo"), None)

        # clear()
        cache.put("foo", "bar")
        self.assertEqual(cache.get("foo"), "bar")
        cache.clear()
        self.check_cache_is_consistent(cache)
        self.assertEqual(cache.get("FOO"), None)
        self.assertEqual(cache.get("foo"), None)

    def test_equal_but_not_identical(self):
        #equal but not identical keys must be treated the same
        cache = self._makeOne(1)
        tuple_one = (1, 1)
        tuple_two = (1, 1)
        cache.put(tuple_one, 42)

        self.assertEqual(cache.get(tuple_one), 42)
        self.assertEqual(cache.get(tuple_two), 42)
        self.check_cache_is_consistent(cache)

        cache = self._makeOne(1)
        cache.put(tuple_one, 42)
        cache.invalidate(tuple_two)
        self.assertEqual(cache.get(tuple_one), None)
        self.assertEqual(cache.get(tuple_two), None)

    def test_perfect_hitrate(self):
        #If cache size equals number of items, expect 100% cache hits
        size = 1000
        cache = self._makeOne(size)

        for count in range(size):
            cache.put(count, "item%s" % count)

        for cache_op in range(10000):
            item = random.randrange(0, size - 1)
            if random.getrandbits(1):
                self.assertEqual(cache.get(item), "item%s" % item)
            else:
                cache.put(item, "item%s" % item)

        self.assertEqual(cache.misses, 0)
        self.assertEqual(cache.evictions, 0)

        self.check_cache_is_consistent(cache)

    def test_imperfect_hitrate(self):
        #If cache size == half the number of items -> hit rate ~50%
        size = 1000
        cache = self._makeOne(size / 2)

        for count in range(size):
            cache.put(count, "item%s" % count)

        hits = 0
        misses = 0
        total_gets = 0
        for cache_op in range(10000):
            item = random.randrange(0, size - 1)
            if random.getrandbits(1):
                entry = cache.get(item)
                total_gets += 1
                self.assertTrue(
                        (entry == "item%s" % item) or
                        entry is None)
                if entry is None:
                    misses += 1
                else:
                    hits += 1
            else:
                cache.put(item, "item%s" % item)

        # Cache hit rate should be roughly 50%
        hit_ratio = hits / float(total_gets) * 100
        self.assertTrue(hit_ratio > 45)
        self.assertTrue(hit_ratio < 55)

        # The internal cache counters should have the same information
        internal_hit_ratio = 100 * cache.hits / cache.lookups
        self.assertTrue(internal_hit_ratio > 45)
        self.assertTrue(internal_hit_ratio < 55)

        # The internal miss counters should also be around 50%
        internal_miss_ratio = 100 * cache.misses / cache.lookups
        self.assertTrue(internal_miss_ratio > 45)
        self.assertTrue(internal_miss_ratio < 55)

        self.check_cache_is_consistent(cache)

    def test_eviction_counter(self):
        cache = self._makeOne(2)
        cache.put(1, 1)
        cache.put(2, 1)
        self.assertEqual(cache.evictions, 0)

        cache.put(3, 1)
        cache.put(4, 1)
        self.assertEqual(cache.evictions, 2)

        cache.put(3, 1)
        cache.put(4, 1)
        self.assertEqual(cache.evictions, 2)

        cache.clear()
        self.assertEqual(cache.evictions, 0)


    def test_it(self):
        cache = self._makeOne(3)
        self.assertEqual(cache.get('a'), None)

        cache.put('a', '1')
        pos, value = cache.data.get('a')
        self.assertEqual(cache.clock_refs[pos], True)
        self.assertEqual(cache.clock_keys[pos], 'a')
        self.assertEqual(value, '1')
        self.assertEqual(cache.get('a'), '1')
        self.assertEqual(cache.hand, pos + 1)

        pos, value = cache.data.get('a')
        self.assertEqual(cache.clock_refs[pos], True)
        self.assertEqual(cache.hand, pos + 1)
        self.assertEqual(len(cache.data), 1)

        cache.put('b', '2')
        pos, value = cache.data.get('b')
        self.assertEqual(cache.clock_refs[pos], True)
        self.assertEqual(cache.clock_keys[pos], 'b')
        self.assertEqual(len(cache.data), 2)

        cache.put('c', '3')
        pos, value = cache.data.get('c')
        self.assertEqual(cache.clock_refs[pos], True)
        self.assertEqual(cache.clock_keys[pos], 'c')
        self.assertEqual(len(cache.data), 3)

        pos, value = cache.data.get('a')
        self.assertEqual(cache.clock_refs[pos], True)

        cache.get('a')
        # All items have ref==True. cache.hand points to "a". Putting
        # "d" will set ref=False on all items and then replace "a",
        # because "a" is the first item with ref==False that is found.
        cache.put('d', '4')
        self.assertEqual(len(cache.data), 3)
        self.assertEqual(cache.data.get('a'), None)

        # Only item "d" has ref==True. cache.hand points at "b", so "b"
        # will be evicted when "e" is inserted. "c" will be left alone.
        cache.put('e', '5')
        self.assertEqual(len(cache.data), 3)
        self.assertEqual(cache.data.get('b'), None)
        self.assertEqual(cache.get('d'), '4')
        self.assertEqual(cache.get('e'), '5')
        self.assertEqual(cache.get('a'), None)
        self.assertEqual(cache.get('b'), None)
        self.assertEqual(cache.get('c'), '3')

        self.check_cache_is_consistent(cache)


class ExpiringLRUCacheTests(LRUCacheTests):

    def _getTargetClass(self):
        from repoze.lru import ExpiringLRUCache
        return ExpiringLRUCache

    def _makeOne(self, size, default_timeout=None):
        if default_timeout is None:
            return self._getTargetClass()(size)
        else:
            return self._getTargetClass()(size, default_timeout=default_timeout)

    def check_cache_is_consistent(self, cache):
        #Return if cache is consistent, else raise fail test case.
        #
        #This is slightly different for ExpiringLRUCache since self.data
        #contains 3-tuples instead of 2-tuples.
        # cache.hand/maxpos/size
        self.assertTrue(cache.hand < len(cache.clock_keys))
        self.assertTrue(cache.hand >= 0)
        self.assertEqual(cache.maxpos, cache.size - 1)
        self.assertEqual(len(cache.clock_keys), cache.size)

        # lengths of data structures
        self.assertEqual(len(cache.clock_keys), len(cache.clock_refs))
        self.assertTrue(len(cache.data) <= len(cache.clock_refs))

        # For each item in cache.data
        #   1. pos must be a valid index
        #   2. clock_keys must point back to the entry
        for key, value in cache.data.items():
            pos, val, timeout = value
            self.assertTrue(
                type(pos) == type(42) or type(pos) == type(2 ** 128))
            self.assertTrue(pos >= 0)
            self.assertTrue(pos <= cache.maxpos)

            clock_key = cache.clock_keys[pos]
            self.assertTrue(clock_key is key)
            clock_ref = cache.clock_refs[pos]

            self.assertTrue(type(timeout) == type(3.141))

        # All clock_refs must be True or False, nothing else.
        for clock_ref in cache.clock_refs:
            self.assertTrue(clock_ref is True or clock_ref is False)

    def test_it(self):
        #Test a sequence of operations
        #
        # Looks at internal data, which is different for ExpiringLRUCache.
        cache = self._makeOne(3)
        self.assertEqual(cache.get('a'), None)

        cache.put('a', '1')
        pos, value, expires = cache.data.get('a')
        self.assertEqual(cache.clock_refs[pos], True)
        self.assertEqual(cache.clock_keys[pos], 'a')
        self.assertEqual(value, '1')
        self.assertEqual(cache.get('a'), '1')
        self.assertEqual(cache.hand, pos + 1)

        pos, value, expires = cache.data.get('a')
        self.assertEqual(cache.clock_refs[pos], True)
        self.assertEqual(cache.hand, pos + 1)
        self.assertEqual(len(cache.data), 1)

        cache.put('b', '2')
        pos, value, expires = cache.data.get('b')
        self.assertEqual(cache.clock_refs[pos], True)
        self.assertEqual(cache.clock_keys[pos], 'b')
        self.assertEqual(len(cache.data), 2)

        cache.put('c', '3')
        pos, value, expires = cache.data.get('c')
        self.assertEqual(cache.clock_refs[pos], True)
        self.assertEqual(cache.clock_keys[pos], 'c')
        self.assertEqual(len(cache.data), 3)

        pos, value, expires = cache.data.get('a')
        self.assertEqual(cache.clock_refs[pos], True)

        cache.get('a')
        # All items have ref==True. cache.hand points to "a". Putting
        # "d" will set ref=False on all items and then replace "a",
        # because "a" is the first item with ref==False that is found.
        cache.put('d', '4')
        self.assertEqual(len(cache.data), 3)
        self.assertEqual(cache.data.get('a'), None)

        # Only item "d" has ref==True. cache.hand points at "b", so "b"
        # will be evicted when "e" is inserted. "c" will be left alone.
        cache.put('e', '5')
        self.assertEqual(len(cache.data), 3)
        self.assertEqual(cache.data.get('b'), None)
        self.assertEqual(cache.get('d'), '4')
        self.assertEqual(cache.get('e'), '5')
        self.assertEqual(cache.get('a'), None)
        self.assertEqual(cache.get('b'), None)
        self.assertEqual(cache.get('c'), '3')

        self.check_cache_is_consistent(cache)

    def test_default_timeout(self):
        #Default timeout provided at init time must be applied.
        # Provide no default timeout -> entries must remain valid
        cache = self._makeOne(3)
        cache.put("foo", "bar")

        time.sleep(0.1)
        cache.put("FOO", "BAR")
        self.assertEqual(cache.get("foo"), "bar")
        self.assertEqual(cache.get("FOO"), "BAR")
        self.check_cache_is_consistent(cache)

        # Provide short default timeout -> entries must become invalid
        cache = self._makeOne(3, default_timeout=0.1)
        cache.put("foo", "bar")

        time.sleep(0.1)
        cache.put("FOO", "BAR")
        self.assertEqual(cache.get("foo"), None)
        self.assertEqual(cache.get("FOO"), "BAR")
        self.check_cache_is_consistent(cache)

    def test_different_timeouts(self):
        #Timeouts must be per entry, default applied when none provided
        cache = self._makeOne(3, default_timeout=0.1)

        cache.put("one", 1)
        cache.put("two", 2, timeout=0.2)
        cache.put("three", 3, timeout=0.3)

        # All entries still here
        self.assertEqual(cache.get("one"), 1)
        self.assertEqual(cache.get("two"), 2)
        self.assertEqual(cache.get("three"), 3)

        # Entry "one" must expire, "two"/"three" remain valid
        time.sleep(0.1)
        self.assertEqual(cache.get("one"), None)
        self.assertEqual(cache.get("two"), 2)
        self.assertEqual(cache.get("three"), 3)

        # Only "three" remains valid
        time.sleep(0.1)
        self.assertEqual(cache.get("one"), None)
        self.assertEqual(cache.get("two"), None)
        self.assertEqual(cache.get("three"), 3)

        # All have expired
        time.sleep(0.1)
        self.assertEqual(cache.get("one"), None)
        self.assertEqual(cache.get("two"), None)
        self.assertEqual(cache.get("three"), None)

        self.check_cache_is_consistent(cache)

    def test_renew_timeout(self):
        #Re-putting an entry must update timeout
        cache = self._makeOne(3, default_timeout=0.2)

        cache.put("foo", "bar")
        cache.put("foo2", "bar2", timeout=10)
        cache.put("foo3", "bar3", timeout=10)

        time.sleep(0.1)
        # All must still be here
        self.assertEqual(cache.get("foo"), "bar")
        self.assertEqual(cache.get("foo2"), "bar2")
        self.assertEqual(cache.get("foo3"), "bar3")
        self.check_cache_is_consistent(cache)

        # Set new timeouts by re-put()ing the entries
        cache.put("foo", "bar")
        cache.put("foo2", "bar2", timeout=0.1)
        cache.put("foo3", "bar3")

        time.sleep(0.1)
        # "foo2" must have expired
        self.assertEqual(cache.get("foo"), "bar")
        self.assertEqual(cache.get("foo2"), None)
        self.assertEqual(cache.get("foo3"), "bar3")
        self.check_cache_is_consistent(cache)


class DecoratorTests(unittest.TestCase):

    def _getTargetClass(self):
        from repoze.lru import lru_cache
        return lru_cache

    def _makeOne(self, maxsize, cache, timeout=None):
        return self._getTargetClass()(maxsize, timeout=timeout, cache=cache)

    def test_ctor_nocache(self):
        decorator = self._makeOne(10, None)
        self.assertEqual(decorator.cache.size, 10)

    def test_singlearg(self):
        cache = DummyLRUCache()
        decorator = self._makeOne(0, cache)
        def wrapped(key):
            return key
        decorated = decorator(wrapped)
        result = decorated(1)
        self.assertEqual(cache[(1,)], 1)
        self.assertEqual(result, 1)
        self.assertEqual(len(cache), 1)
        result = decorated(2)
        self.assertEqual(cache[(2,)], 2)
        self.assertEqual(result, 2)
        self.assertEqual(len(cache), 2)
        result = decorated(2)
        self.assertEqual(cache[(2,)], 2)
        self.assertEqual(result, 2)
        self.assertEqual(len(cache), 2)

    def test_cache_attr(self):
        cache = DummyLRUCache()
        decorator = self._makeOne(0, cache)
        def wrapped(key): #pragma NO COVER
            return key
        decorated = decorator(wrapped)
        self.assertTrue(decorated._cache is cache)

    def test_multiargs(self):
        cache = DummyLRUCache()
        decorator = self._makeOne(0, cache)
        def moreargs(*args):
            return args
        decorated = decorator(moreargs)
        result = decorated(3, 4, 5)
        self.assertEqual(cache[(3, 4, 5)], (3, 4, 5))
        self.assertEqual(result, (3, 4, 5))
        self.assertEqual(len(cache), 1)

    def test_expiry(self):
        #When timeout is given, decorator must eventually forget entries
        @self._makeOne(1, None, timeout=0.1)
        def sleep_a_bit(param):
            time.sleep(0.1)
            return 2 * param

        # First call must take at least 0.1 seconds
        start = time.time()
        result1 = sleep_a_bit("hello")
        stop = time.time()
        self.assertEqual(result1, 2 * "hello")
        self.assertTrue(stop - start > 0.1)

        # Second call must take less than 0.1 seconds.
        start = time.time()
        result2 = sleep_a_bit("hello")
        stop = time.time()
        self.assertEqual(result2, 2 * "hello")
        self.assertTrue(stop - start < 0.1)

        time.sleep(0.1)
        # This one must calculate again and take at least 0.1 seconds
        start = time.time()
        result3 = sleep_a_bit("hello")
        stop = time.time()
        self.assertEqual(result3, 2 * "hello")
        self.assertTrue(stop - start > 0.1)

    def test_partial(self):
        #lru_cache decorator must not crash on functools.partial instances
        def add(a,b):
            return a + b
        from functools import partial
        from repoze.lru import lru_cache
        add_five = partial(add, 5)
        decorated = lru_cache(20)(add_five)
        self.assertEqual(decorated(3), 8)


class DummyLRUCache(dict):

    def put(self, k, v):
        return self.__setitem__(k, v)


class CacherMaker(unittest.TestCase):

    def _getTargetClass(self):
        from repoze.lru import CacheMaker
        return CacheMaker

    def _makeOne(self, *args, **kw):
        return self._getTargetClass()(*args, **kw)

    def test_named_cache(self):
        maker = self._makeOne()
        size = 10
        name = "name"
        decorated = maker.lrucache(maxsize=size, name=name)(_adder)
        self.assertEqual(list(maker._cache.keys()), [name])
        self.assertEqual(maker._cache[name].size, size)
        decorated(10)
        decorated(11)
        self.assertEqual(len(maker._cache[name].data),2)

    def test_exception(self):
        maker = self._makeOne()
        size = 10
        name = "name"
        decorated = maker.lrucache(maxsize=size, name=name)(_adder)
        self.assertRaises(KeyError, maker.lrucache, maxsize=size, name=name)
        self.assertRaises(ValueError, maker.lrucache)

    def test_defaultvalue_and_clear(self):
        size = 10
        maker = self._makeOne(maxsize=size)
        for i in range(100):
            decorated = maker.lrucache()(_adder)
            decorated(10)

        self.assertEqual(len(maker._cache) , 100)
        for _cache in maker._cache.values():
            self.assertEqual( _cache.size,size)
            self.assertEqual(len(_cache.data),1)
        ## and test clear cache
        maker.clear()
        for _cache in maker._cache.values():
            self.assertEqual( _cache.size,size)
            self.assertEqual(len(_cache.data),0)

    def test_clear_with_single_name(self):
        maker = self._makeOne(maxsize=10)
        one = maker.lrucache(name='one')(_adder)
        two = maker.lrucache(name='two')(_adder)
        for i in range(100):
            _ = one(i)
            _ = two(i)
        self.assertEqual(len(maker._cache['one'].data), 10)
        self.assertEqual(len(maker._cache['two'].data), 10)
        maker.clear('one')
        self.assertEqual(len(maker._cache['one'].data), 0)
        self.assertEqual(len(maker._cache['two'].data), 10)

    def test_clear_with_multiple_names(self):
        maker = self._makeOne(maxsize=10)
        one = maker.lrucache(name='one')(_adder)
        two = maker.lrucache(name='two')(_adder)
        three = maker.lrucache(name='three')(_adder)
        for i in range(100):
            _ = one(i)
            _ = two(i)
            _ = three(i)
        self.assertEqual(len(maker._cache['one'].data), 10)
        self.assertEqual(len(maker._cache['two'].data), 10)
        self.assertEqual(len(maker._cache['three'].data), 10)
        maker.clear('one', 'three')
        self.assertEqual(len(maker._cache['one'].data), 0)
        self.assertEqual(len(maker._cache['two'].data), 10)
        self.assertEqual(len(maker._cache['three'].data), 0)

    def test_expiring(self):
        size = 10
        timeout = 10
        name = "name"
        cache = self._makeOne(maxsize=size, timeout=timeout)
        for i in range(100):
            if not i:
                decorated = cache.expiring_lrucache(name=name)(_adder)
                self.assertEqual( cache._cache[name].size,size)
            else:
                decorated = cache.expiring_lrucache()(_adder)
            decorated(10)

        self.assertEqual( len(cache._cache) , 100)
        for _cache in cache._cache.values():
            self.assertEqual( _cache.size,size)
            self.assertEqual( _cache.default_timeout,timeout)
            self.assertEqual(len(_cache.data),1)
        ## and test clear cache
        cache.clear()
        for _cache in cache._cache.values():
            self.assertEqual( _cache.size,size)
            self.assertEqual(len(_cache.data),0)

def _adder(x):
    return x + 10
