# barbacompta - invoicing for dummies
# Copyright (C) 2019-2020 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import hashlib
from functools import wraps


def compute_key(func, *args, **kwargs):
    keys = [str(id(func))] + [str(arg) for arg in args] + sorted(str(k) + str(v) for k, v in kwargs.items())
    return hashlib.md5(''.join(keys).encode('utf-8')).hexdigest()


cached_func = set()


def cache(func):
    from django.core.cache import cache

    sentinel = object()

    def compute(*args, **kwargs):
        key = compute_key(func, *args, **kwargs)
        result = func(*args, **kwargs)
        cache.set(key, result, 600)
        return result

    @wraps(func)
    def f(*args, **kwargs):
        key = compute_key(func, *args, **kwargs)
        result = cache.get(key, sentinel)
        if result is sentinel:
            return compute(*args, **kwargs)
        return result

    f.recompute = compute
    cached_func.add(f)
    return f
