# (c) cavaliba.com - home - cache.py

import os
import copy

from django.core.cache import cache as django_cache


# cookie/session : per user ; logout to clear ; aaa
# localmem       : per request 
# localmem       : per multiple request
# django (redis) : timeout per cache

# -----------------------------------------
# GENERIC CAVALIBA CACHE
# -----------------------------------------

class DataCache():


    def __init__(self, cachename=None, timeout=10):

        self.cachename = cachename
        self.localmem = {}
        
        self.timeout = timeout    # django cache default timeout

        self.tenant = os.environ.get("CAVALIBA_TENANT", default="cavaliba")
        self.prefix = f"{self.tenant}::cache::{self.cachename}"



    def fullkeyname(self, key):
        return f"{self.prefix}::{key}"



    def get(self, key=None):
        
        if not key:
            return
        
        # add tenant/cache prefix
        fullkeyname = self.fullkeyname(key)

        # 1. search inmemory cache
        if fullkeyname in self.localmem:
            return copy.deepcopy(self.localmem[fullkeyname])
        
        # 2. django Cache (redis, memcache, ...)
        a = django_cache.get(fullkeyname)
        if a:
            self.localmem[fullkeyname] = copy.deepcopy(a)
            return a




    def set(self,key=None, value=None):

        if not key:
            return
        
        # add tenant/cache prefix
        fullkeyname = self.fullkeyname(key)
        
        try:
            self.localmem[fullkeyname] = copy.deepcopy(value)
        except:
            pass

        try:
            django_cache.set(fullkeyname, value, self.timeout)
        except:
            pass



    def delete(self, key):


        if not key:
            return
        
        # add tenant/cache prefix
        fullkeyname = self.fullkeyname(key)

        self.localmem.pop(fullkeyname, None)
        django_cache.delete(fullkeyname)



    def clear(self):

        self.localmem = {}
        django_cache.delete_many(keys=django_cache.keys(f"{self.prefix}::*"))


# -----------------------------------------
# cache
# -----------------------------------------

cache_configuration = {}
cache2_configuration = DataCache(cachename="cache2_configuration", timeout=60)

# per hit only 
cache_aaa = {}

# Schema()
cache2_schema = DataCache(cachename="cache2_schema", timeout=60)

# Instance()
cache2_instance = DataCache(cachename="cache2_instance", timeout=60)

# data content of enumerate object
cache2_enumerate = DataCache(cachename="cache2_enumerate", timeout=120)

# dict datapoint
cache2_datapoint = DataCache(cachename="cache2_datapoint", timeout=60)

#  DB SireneUser objects
cache2_iam_user = DataCache(cachename="cache2_iam_user", timeout=120)

def clear():
    ''' empty all caches'''


    # TODO
    global cache_configuration
    cache_configuration = {}


    global cache_aaa
    cache_aaa={}

    global cache2_schema
    cache2_schema.clear()

    global cache2_configuration
    cache2_configuration.clear()

    global cache2_instance
    cache2_instance.clear()

    global cache2_enumerate         # preprocessed enum data structure
    cache2_enumerate.clear()

    global cache2_datapoint
    cache2_datapoint.clear()

    global cache2_iam_user
    cache2_iam_user.clear()


# Per HIT / REQUEST cache reset
def init():
    ''' empty per-request cache'''

    # TODO
    global cache_configuration
    cache_configuration = {}

    # new

    global cache_aaa
    cache_aaa={}

    global cache2_schema
    cache2_schema.localmem = {}

    global cache2_configuration
    cache2_configuration.localmem = {}

    global cache2_instance
    cache2_instance.localmem = {}

    global cache2_enumerate
    cache2_enumerate.localmem = {}

    global cache2_datapoint
    cache2_datapoint.localmem = {}

    global cache2_iam_user
    cache2_iam_user.localmem = {}
