# coding: utf-8

from __future__ import unicode_literals

from django.conf import settings
from django.db import connection

from .cache import cachalot_caches
from .utils import _get_table_cache_key, _invalidate_table_cache_keys


__all__ = ('invalidate_tables', 'invalidate_models', 'invalidate_all')


def invalidate_tables(tables, cache_alias=None, db_alias=None):
    """
    Clears what was cached by django-cachalot implying one or more SQL tables
    from ``tables``.

    If ``cache_alias`` is specified, it only clears the SQL queries stored
    on this cache, otherwise the current cache is cleared.

    If ``db_alias`` is specified, it only clears the SQL queries executed
    on this database, otherwise queries from the current database are cleared.

    :arg tables: SQL tables names
    :type tables: iterable of strings
    :arg cache_alias: Alias from the Django ``CACHES`` setting
    :type cache_alias: string or NoneType
    :arg db_alias: Alias from the Django ``DATABASES`` setting
    :type db_alias: string or NoneType
    :returns: Nothing
    :rtype: NoneType
    """

    if db_alias is None:
        db_alias = connection.alias

    table_cache_keys = [_get_table_cache_key(db_alias, t) for t in tables]
    cache = cachalot_caches.get_cache(cache_alias)
    _invalidate_table_cache_keys(cache, table_cache_keys)


def invalidate_models(models, cache_alias=None, db_alias=None):
    """
    Shortcut for ``invalidate_tables`` where you can specify Django models
    instead of SQL table names.

    :arg models: Django models
    :type models: iterable of ``django.db.models.Model`` subclasses
    :arg cache_alias: Alias from the Django ``CACHES`` setting
    :type cache_alias: string or NoneType
    :arg db_alias: Alias from the Django ``DATABASES`` setting
    :type db_alias: string or NoneType
    :returns: Nothing
    :rtype: NoneType
    """

    invalidate_tables([model._meta.db_table for model in models],
                      cache_alias, db_alias)


def invalidate_all(cache_alias=None, db_alias=None):
    """
    Clears everything that was cached by django-cachalot.

    If ``cache_alias`` is specified, it only clears the SQL queries stored
    on this cache, otherwise all caches are cleared.

    If ``db_alias`` is specified, it only clears the SQL queries executed
    on this database, otherwise queries from all databases are cleared.

    :arg cache_alias: Alias from the Django ``CACHES`` setting
    :type cache_alias: string or NoneType
    :arg db_alias: Alias from the Django ``DATABASES`` setting
    :type cache_alias: string or NoneType
    :returns: Nothing
    :rtype: NoneType
    """

    cache_aliases = settings.CACHES if cache_alias is None else (cache_alias,)
    db_aliases = settings.DATABASES if db_alias is None else (db_alias,)
    for cache_alias in cache_aliases:
        for db_alias in db_aliases:
            cachalot_caches.invalidate_all(cache_alias, db_alias)
