"""Settings to use when testing the project

Tests may not work without these settings
"""

import logging
import os

from django.conf import global_settings

from .base import *  # pylint: disable=wildcard-import


DEBUG = False

# Ensure we always run tests the same way. One day we should have
# two jenkins jobs to run both configurations
# Pass the env variable ``DONT_ENFORCE_SLAVE_IN_TESTS=True`` to use
# the ``MTP_INSTANCE_IS_SLAVE`` from your environment
if not get_bool_env_variable('DONT_ENFORCE_SLAVE_IN_TESTS', default=False):
    INSTANCE_IS_SLAVE = True
    INSTANCE_IS_MASTER = False

if get_bool_env_variable('INSTALL_MTP_TEST_APPS', default=True):
    INSTALLED_APPS += [
        # Some test cases define new django models only for test purpose, so to let
        # django create the db table, they must be apps in ``INSTALLED_APPS``
        'mtp.apps.api.tests.api_testapp',
        'mtp.apps.broker_models_hooks.tests.broker_models_hooks_testapp',
        'mtp.apps.common.tests.limpyd_base',
        'mtp.apps.common.tests.common_testapp',
        'mtp.discrete_apps.versionable.tests.versionable_testapp',
        'mtp.discrete_apps.duplicable.tests.duplicable_testapp',
        'mtp.apps.likes.tests.likeable_testapp',
        'mtp.apps.media.tests.media_testapp',
        'mtp.apps.pdf_reporting.tests.pdf_reporting_testapp',
        'mtp.apps.sync.tests.syncable_testapp',
    ]

# See https://docs.djangoproject.com/en/1.8/topics/testing/overview/#speeding-up-the-tests
PASSWORD_HASHERS = [
    'django.contrib.auth.hashers.MD5PasswordHasher',
]

# Use a storage backend that stores file in memory to gain speed and avoid polluting the disk.
DJANGO_DEFAULT_FILE_STORAGE = global_settings.DEFAULT_FILE_STORAGE
DEFAULT_FILE_STORAGE = 'inmemorystorage.storage.InMemoryStorage'
INMEMORYSTORAGE_PERSIST = True  # to keep files in memory between tests

# Use a specific folder for tests medias, and keep a ref of the default one to copy default files
TESTS_MEDIA_ROOT = get_env_variable('MTP_TESTS_MEDIA_ROOT',
                                    default=os.path.join(MEDIA_ROOT, 'tests'))
DEFAULT_MEDIA_ROOT, MEDIA_ROOT = MEDIA_ROOT, TESTS_MEDIA_ROOT

# Update settings depending on MEDIA_ROOT
PGDUMP_SAVE_ROOT = os.path.join(MEDIA_ROOT, 'pgdump')
REV_SAVE_ROOT = os.path.join(MEDIA_ROOT, 'revision')
UPLOAD_ROOT = os.path.join(MEDIA_ROOT, 'upload')

# Will record/compare sql/cache usage on each test if set to True
USE_PERF_REC = get_bool_env_variable('USE_PERF_REC', default=False)

USE_FAKEREDIS = get_bool_env_variable('USE_FAKEREDIS', default=True)

if USE_FAKEREDIS:
    # Make the cache use ``fakeredis`` if it is configured to use redis.
    if get_bool_env_variable('USE_REDIS_FOR_CACHE', default=True):
        CACHES['default']['BACKEND'] = 'mtp.apps.common.tests.redis_cache.FakeRedisCache'

    # Make the sessions use ``fakeredis`` if they are configured to use redis.
    if get_bool_env_variable('USE_REDIS_FOR_SESSIONS', default=True):
        SESSION_ENGINE = 'mtp.apps.common.tests.redis_session'

    # Make all our limpyd models use ``fakeredis``.
    # pylint: disable=wrong-import-position
    from mtp.apps.common.limpyd_base import BaseModel
    from mtp.apps.common.tests.limpyd_base.limpyd_database import LIMPYD_TEST_DATABASE
    BaseModel.use_database(LIMPYD_TEST_DATABASE)

    # Make django-constance use fake-redis
    CONSTANCE_BACKEND = 'constance.backends.redisd.RedisBackend'
    CONSTANCE_REDIS_CONNECTION_CLASS = 'mtp.apps.common.tests.redis_constance.get_redis_connection'

for logger_name in ('factory', 'duplicate'):
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.ERROR)


if get_bool_env_variable('TESTS_SKIP_MIGRATIONS', default=False):
    """
    Hack to disable migrations for tests. It both makes creating the test database quicker,
    and allows experimenting without having to create migrations for each model change.
    It has no effect if you are reusing the database (which is the default with py.test).

    Do not use if you want to tests newly added migrations.

    Run it like this:
    $ TESTS_SKIP_MIGRATIONS='True' py.test --create-db path.to.tests

    """  # pylint: disable=pointless-string-statement

    class DisableMigrations(object):
        """
        Hack to disable migrations for tests. It both makes creating the test database quicker,
        and allows experimenting without having to create migrations for each model change.
        It has no effect if you are reusing the database (which is the default).

        Do not use if you want to tests newly added migrations.

        http://stackoverflow.com/questions/25161425/disable-migrations-when-running-unit-tests-in-django-1-7#comment43230116_25267435

        Te be set in settings this way:

            MIGRATIONS_MODULE = DisableMigrations
        """

        def __contains__(self, app_label):
            """
            Always return True to tell django we have the migrations for all the apps.
            Then in `__getitem__` we'll return an invalid migration.
            """
            return True

        def __getitem__(self, app_label):
            """
            Always return a invalid migration to tell django to skip trying to apply
            this migration.
            """
            return None

    MIGRATION_MODULES = DisableMigrations()

# we want to test `discrete_apps.saba` w/ models and migrations
if 'mtp.discrete_apps.saba' not in INSTALLED_APPS:
    INSTALLED_APPS.append('mtp.discrete_apps.saba')

# Celery setttings for tests
# --------------------------

# See http://docs.celeryproject.org/en/2.5/django/unit-testing.html
#
# If you want to, you can also run a real Celery worker in the background.
#
# To do so, you'll need :
# - A working redis instance (as defined in settings/base.py)
# - Set the ENV var `CELERY_ALWAYS_EAGER` to False (CELERY_ALWAYS_EAGER='False')
# - Launch the Celery worker:
# >>> celery worker -A mtp --loglevel=INFO

CELERY_ALWAYS_EAGER = get_bool_env_variable('CELERY_ALWAYS_EAGER', default=True)
