# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Caching utilities.
"""

from __future__ import absolute_import  # so we can import standard 'collections' and 'threading'

from threading import Lock
from functools import partial

from .collections import OrderedDict


class cachedmethod(object):  # pylint: disable=invalid-name
    """
    Decorator for caching method return values.

    The implementation is thread-safe.

    Supports ``cache_info`` to be compatible with Python 3's ``functools.lru_cache``. Note that the
    statistics are combined for all instances of the class.

    Won't use the cache if not called when bound to an object, allowing you to override the cache.

    Adapted from `this solution
    <http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/>`__.
    """

    ENABLED = True

    def __init__(self, func):
        self.__doc__ = func.__doc__
        self.func = func
        self.hits = 0
        self.misses = 0
        self.lock = Lock()

    def cache_info(self):
        with self.lock:
            return (self.hits, self.misses, None, self.misses)

    def reset_cache_info(self):
        with self.lock:
            self.hits = 0
            self.misses = 0

    def __get__(self, instance, owner):
        if instance is None:
            # Don't use cache if not bound to an object
            # Note: This is also a way for callers to override the cache
            return self.func
        return partial(self, instance)

    def __call__(self, *args, **kwargs):
        if not self.ENABLED:
            return self.func(*args, **kwargs)

        instance = args[0]
        if not hasattr(instance, '_method_cache'):
            instance._method_cache = {}
        method_cache = instance._method_cache

        key = (self.func, args[1:], frozenset(kwargs.items()))

        try:
            with self.lock:
                return_value = method_cache[key]
                self.hits += 1
        except KeyError:
            return_value = self.func(*args, **kwargs)
            with self.lock:
                method_cache[key] = return_value
                self.misses += 1
            # Another thread may override our cache entry here, so we need to read
            # it again to make sure all threads use the same return value
            return_value = method_cache.get(key, return_value)

        return return_value


class HasCachedMethods(object):
    """
    Provides convenience methods for working with :class:`cachedmethod`.
    """

    def __init__(self, method_cache=None):
        self._method_cache = method_cache or {}

    @property
    def _method_cache_info(self):
        """
        The cache infos of all cached methods.

        :rtype: dict of str, 4-tuple
        """

        cached_info = OrderedDict()
        for k, v in self.__class__.__dict__.iteritems():
            if isinstance(v, property):
                # The property getter might be cached
                v = v.fget
            if hasattr(v, 'cache_info'):
                cached_info[k] = v.cache_info()
        return cached_info

    def _reset_method_cache(self):
        """
        Resets the caches of all cached methods.
        """

        if hasattr(self, '_method_cache'):
            self._method_cache = {}

        # Note: Another thread may already be storing entries in the cache here.
        # But it's not a big deal! It only means that our cache_info isn't
        # guaranteed to be accurate.

        for entry in self.__class__.__dict__.itervalues():
            if isinstance(entry, property):
                # The property getter might be cached
                entry = entry.fget
            if hasattr(entry, 'reset_cache_info'):
                entry.reset_cache_info()
