# -*- coding: utf-8 -*-
import logging
from datetime import datetime
from zope.component import getAllUtilitiesRegisteredFor
from zope.component import getUtility
from zope.component import queryUtility
from zope.schema.interfaces import IVocabularyFactory
from plone import api
from plone.i18n.normalizer import IIDNormalizer
from plone.memoize.instance import Memojito
from plone.memoize.interfaces import ICacheChooser


logger = logging.getLogger('imio.helpers:cache')


def cleanVocabularyCacheFor(vocabulary=None):
    """Clean _memojito_ attribute for given p_vocabulary name.
       If p_vocabulary is None, it will clean every vocabulary _memojito_ attribute."""

    # we received a vocabulary name, just clean this one
    if vocabulary:
        vocabularies = (queryUtility(IVocabularyFactory, vocabulary), )
    else:
        # clean every vocabularies having a _memojito_ attribute
        vocabularies = getAllUtilitiesRegisteredFor(IVocabularyFactory)

    for vocab in vocabularies:
        if hasattr(vocab, Memojito.propname):
            getattr(vocab, Memojito.propname).clear()


def cleanRamCache():
    """Clean the entire ram.cache."""
    cache_chooser = getUtility(ICacheChooser)
    thecache = cache_chooser('')
    thecache.ramcache.invalidateAll()


def cleanRamCacheFor(methodId, obj=None):
    """Clean ram.cache for given p_methodId."""
    cache_chooser = getUtility(ICacheChooser)
    thecache = cache_chooser(methodId)
    thecache.ramcache.invalidate(methodId)


def get_cachekey_volatile(name):
    """Helper for using a volatile corresponding to p_name
       to be used as cachekey stored in a volatile.
       If it exists, we return the value, either we store datetime.now()."""
    portal = api.portal.get()
    # use max_length of 200 to avoid cropped names that could lead to
    # having 2 names beginning with same part using same volatile...
    normalized_name = queryUtility(IIDNormalizer).normalize(name, max_length=200)
    volatile_name = '_v_{0}'.format(normalized_name)
    date = getattr(portal, volatile_name, None)
    if not date:
        date = datetime.now()
        setattr(portal, volatile_name, date)
    return date


def invalidate_cachekey_volatile_for(name):
    """ """
    portal = api.portal.get()
    normalized_name = queryUtility(IIDNormalizer).normalize(name, max_length=200)
    volatile_name = '_v_{0}'.format(normalized_name)
    if hasattr(portal, volatile_name):
        delattr(portal, volatile_name)
