# This file is sourced by "execfile" from django settings

# Example of django settings.py:
#
# (...)
# PROJECT_NAME = 'name'
# INSTALLED_APPS += ('mellon',)   # SAML2 authentication
# execfile('/usr/lib/hoho/debian_config_common.py')
# execfile('/etc/%s/settings.py' % PROJECT_NAME)

import os
import warnings

import django
from django.conf import global_settings
from django.core.exceptions import ImproperlyConfigured

USE_TENANT_WSGI_MIDDLEWARE = os.environ.get('USE_TENANT_WSGI_MIDDLEWARE') == '1'

if USE_TENANT_WSGI_MIDDLEWARE and PROJECT_NAME != 'wcs':
    WSGI_APPLICATION = 'hobo.multitenant.wsgi.application'

DEBUG = False

with open('/etc/%s/secret' % PROJECT_NAME) as fd:
    SECRET_KEY = fd.read().strip()

ADMINS = (('Tous', 'root@localhost'),)

MIGRATE_SCHEMAS_JOBS = 1

EMAIL_SUBJECT_PREFIX = ''

# This prevents sockets created in smtplib to rely on the default timeout
# by setting their timeout value to 10 seconds.
EMAIL_TIMEOUT = 10.0

# send the SMTP Date header of email messages in the local time zone
# (since Django 1.11)
EMAIL_USE_LOCALTIME = True

# For high availability installations with multiple instances of Publik
# components, one should disable cron jobs execution on secondary servers;
# set the following variable True disables all tenant_commands launched with
# option "--all-tenants".
DISABLE_CRON_JOBS = False

# mode for newly updated files
FILE_UPLOAD_PERMISSIONS = 0o644

DEBUG_PROVISIONNING_LOG_PATH = '/var/log/%s/provisionning-debug' % PROJECT_NAME

DISABLE_GLOBAL_HANDLERS = os.environ.get('DISABLE_GLOBAL_HANDLERS') == '1'


LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
        'request_context': {
            '()': 'hobo.logger.RequestContextFilter',
        },
        'force_debug': {
            '()': 'hobo.logger.ForceDebugFilter',
        },
        'debug_log': {
            '()': 'hobo.logger.DebugLogFilter',
        },
        'clamp_to_warning': {
            '()': 'hobo.logger.ClampLogLevel',
            'level': 'WARNING',
        },
        'ignore_permission_denied': {
            '()': 'hobo.logger.IgnorePermissionDenied',
        },
    },
    'formatters': {
        'syslog': {
            'format': '%(application)s %(levelname)s %(tenant)s %(ip)s %(user)s %(session_id)s %(request_id)s'
            ' %(message)s',
        },
        'syslog_no_filter': {
            'format': '%(levelname)s %(message)s',
        },
    },
    'handlers': {
        'syslog': {
            'level': 'INFO',
            'address': '/dev/log',
            'class': 'logging.handlers.SysLogHandler',
            'formatter': 'syslog',
            'filters': ['request_context'],
        },
        'syslog_no_filter': {
            'level': 'INFO',
            'address': '/dev/log',
            'class': 'logging.handlers.SysLogHandler',
            'formatter': 'syslog_no_filter',
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'hobo.multitenant.log.AdminEmailHandler',
            'include_html': True,
        },
        'null': {
            'class': 'logging.NullHandler',
        },
    },
    'loggers': {
        'django.db': {
            # even when debugging seeing SQL queries is too much
            'level': 'INFO',
        },
        'django': {
            # Override Django default values
            'handlers': [],
            'level': 'NOTSET',
            'propagate': True,
        },
        'django.server': {
            # Override Django 1.8 default values
            'handlers': [],
            'level': 'NOTSET',
            'propagate': True,
        },
        'django.request': {
            # Override Django default values
            'handlers': [],
            'filters': ['ignore_permission_denied'],
            'propagate': True,
        },
        'django.security': {
            # Override Django default values
            'handlers': [],
            'level': 'NOTSET',
            'propagate': True,
        },
        'django.security.SuspiciousFileOperation': {
            'filters': ['clamp_to_warning'],
        },
        'django.security.DisallowedRedirect': {
            'filters': ['clamp_to_warning'],
        },
        'django.security.DisallowedHost': {
            'filters': ['clamp_to_warning'],
        },
        'django.template': {
            # too much logs on DEBUG level
            'handlers': [],
            'level': 'INFO',
            'propagate': True,
        },
        # lasso has the bad habit of logging everything as errors
        'Lasso': {
            'filters': ['force_debug'],
        },
        'libxml2': {
            'filters': ['force_debug'],
        },
        'libxmlsec': {
            'filters': ['force_debug'],
        },
        # log py.warnings to syslog
        'py.warnings': {
            'handlers': [] if DISABLE_GLOBAL_HANDLERS else ['syslog_no_filter'],
            'level': 'WARNING',
            'propagate': False,
        },
        '': {
            'level': 'DEBUG',
            'filters': ['request_context', 'debug_log'],
            'handlers': ([] if DISABLE_GLOBAL_HANDLERS else ['syslog']) + ['mail_admins'],
        },
    },
}

# Journald support
if os.path.exists('/run/systemd/journal/socket') and not DISABLE_GLOBAL_HANDLERS:
    systemd = None
    try:
        import cysystemd as systemd
    except ImportError:
        try:
            import systemd
        except ImportError:
            pass
    if systemd:
        LOGGING['handlers']['journald'] = {
            'level': 'DEBUG',
            'class': 'hobo.journal.JournalHandler',
            'filters': ['request_context', 'debug_log'],
            'formatter': 'syslog',
        }
        LOGGING['loggers']['']['handlers'].remove('syslog')
        LOGGING['loggers']['']['handlers'].append('journald')

elif not os.path.exists('/dev/log') and not DISABLE_GLOBAL_HANDLERS:
    # if three's no syslog (for example when building a docker image), remove
    # those loggers.
    LOGGING['loggers']['']['handlers'].remove('syslog')
    LOGGING['loggers']['py.warnings']['handlers'].remove('syslog_no_filter')
    del LOGGING['handlers']['syslog']
    del LOGGING['handlers']['syslog_no_filter']


ETC_DIR = '/etc/%s' % PROJECT_NAME
VAR_DIR = '/var/lib/%s' % PROJECT_NAME

# collecstatic destination
STATIC_ROOT = os.path.join(VAR_DIR, 'collectstatic')

# template settings
assert len(TEMPLATES)
assert TEMPLATES[0]['BACKEND'] == 'django.template.backends.django.DjangoTemplates'

if not 'loaders' in TEMPLATES[0]['OPTIONS']:
    TEMPLATES[0]['APP_DIRS'] = False
    TEMPLATES[0]['OPTIONS']['loaders'] = [
        'django.template.loaders.filesystem.Loader',
        'django.template.loaders.app_directories.Loader',
    ]
if PROJECT_NAME != 'wcs':
    TEMPLATES[0]['OPTIONS']['loaders'].insert(0, 'hobo.multitenant.template_loader.FilesystemLoader')

if not 'django.template.context_processors.request' in TEMPLATES[0]['OPTIONS']['context_processors']:
    TEMPLATES[0]['OPTIONS']['context_processors'].insert(0, 'django.template.context_processors.request')

TEMPLATES[0]['OPTIONS']['context_processors'] = [
    'hobo.context_processors.template_vars',
    'hobo.context_processors.theme_base',
    'hobo.context_processors.portal_agent_url',
    'hobo.context_processors.user_urls',
] + TEMPLATES[0]['OPTIONS']['context_processors']

# needed by hobo.context_processors.theme_base:
# THEME_SKELETON_URL = 'https://www.example.net/__skeleton__'

# Browsers may ensure that cookies are only sent under an HTTPS connection
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_AGE = 36000  # 10h

# See https://dev.entrouvert.org/issues/100122
SESSION_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_SAMESITE = 'Lax'

# Apply sessionNotOnOrAfter on session expiration date
SESSION_ENGINE = 'mellon.sessions_backends.cached_db'

# make it easier to use runserver behind nginx as reverse proxy
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

if 'MIDDLEWARE' not in globals():
    MIDDLEWARE = global_settings.MIDDLEWARE

MIDDLEWARE = (
    'hobo.middleware.harakiri.harakiri',
    'hobo.middleware.ping.PingMiddleware',  # /__ping__
    'hobo.middleware.security.content_security_policy_middleware',
    'hobo.middleware.VersionMiddleware',  # /__version__
    'hobo.middleware.cors.CORSMiddleware',
    'hobo.middleware.maintenance.MaintenanceMiddleware',
    'hobo.middleware.wellknown.WellKnownMiddleware',  # ex. to serve /.well-known/assetlinks.json
) + MIDDLEWARE

# declare publik-base-theme in installed apps, to get translations
if not os.environ.get('PYTEST_VERSION'):
    INSTALLED_APPS += ('publik_base_theme',)

if 'django.middleware.common.CommonMiddleware' in MIDDLEWARE:
    common_middleware_index = MIDDLEWARE.index('django.middleware.common.CommonMiddleware')
    MIDDLEWARE = (
        MIDDLEWARE[:common_middleware_index]
        + ('hobo.middleware.common.HoboCommonMiddleware',)
        + MIDDLEWARE[common_middleware_index + 1 :]
    )

if PROJECT_NAME != 'wcs':
    MIDDLEWARE = (
        ('hobo.middleware.RobotsTxtMiddleware',)
        + MIDDLEWARE
        + ('hobo.middleware.backoffice_access.BackofficeAccessMiddleware',)
    )

if PROJECT_NAME != 'wcs' and 'authentic' not in PROJECT_NAME:
    MIDDLEWARE = MIDDLEWARE + (
        'mellon.middleware.PassiveAuthenticationMiddleware',
        'hobo.provisionning.middleware.ProvisionningMiddleware',
    )
if PROJECT_NAME != 'wcs':
    INSTALLED_APPS += ('hobo.user_name.apps.UserNameConfig',)

if 'authentic' in PROJECT_NAME:
    MIDDLEWARE = MIDDLEWARE + ('hobo.agent.authentic2.middleware.ProvisionningMiddleware',)

# Allow big provisionning messages
if 'DATA_UPLOAD_MAX_MEMORY_SIZE' not in globals():
    DATA_UPLOAD_MAX_MEMORY_SIZE = 50_000_000

if PROJECT_NAME != 'wcs':
    # multitenant adaptations

    TENANT_BASE = os.path.join(VAR_DIR, 'tenants')
    TENANT_MODEL = 'multitenant.Tenant'
    TENANT_LIMIT_SET_CALLS = True

    if not USE_TENANT_WSGI_MIDDLEWARE:
        MIDDLEWARE = ('hobo.multitenant.middleware.TenantMiddleware',) + MIDDLEWARE

    MIDDLEWARE = ('hobo.middleware.debug.InternalIPMiddleware',) + MIDDLEWARE

    DATABASES = {
        'default': {
            'ENGINE': 'tenant_schemas.postgresql_backend',
            'NAME': PROJECT_NAME.replace('-', '_'),
        }
    }

    DATABASE_ROUTERS = ('tenant_schemas.routers.TenantSyncRouter',)

    TENANT_SETTINGS_LOADERS = (
        'hobo.multitenant.settings_loaders.TemplateVars',
        'hobo.multitenant.settings_loaders.KnownServices',
        'hobo.multitenant.settings_loaders.LegacyURLSSettings',
        'hobo.multitenant.settings_loaders.ThemeSettings',
        'hobo.multitenant.settings_loaders.CORSSettings',
        'hobo.multitenant.settings_loaders.SharedThemeSettings',
        'hobo.multitenant.settings_loaders.Mellon',
        'hobo.multitenant.settings_loaders.SiteBaseUrl',
        'hobo.multitenant.settings_loaders.CookieNames',
        'hobo.multitenant.settings_loaders.BackofficeLoginHint',
        'hobo.multitenant.settings_loaders.SettingsJSON',
        'hobo.multitenant.settings_loaders.SettingsVars',
    )

    # templates in <tenant>/templates
    TENANT_TEMPLATE_DIRS = (TENANT_BASE,)

    # /media in <tenant>/media
    STORAGES = {
        'default': {'BACKEND': 'hobo.multitenant.storage.TenantFileSystemStorage'},
        'staticfiles': {'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage'},
    }

    # cache by tenant
    CACHES = {
        'default': {
            'BACKEND': 'hobo.multitenant.cache.TenantCache',
            # add a real Django cache backend, with its parameters if needed
            'REAL_BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
            'LOCATION': '127.0.0.1:11211',
            'OPTIONS': {'ignore_exc': True},
        }
    }

    # haystack by tenant
    HAYSTACK_CONNECTIONS = {
        'default': {
            'ENGINE': 'hobo.multitenant.haystack.WhooshEngine',
        }
    }

    # multitenant SHARED_APPS/TENANT_APPS/INSTALLED_APPS organization
    SHARED_APPS = ()

    INSTALLED_APPS = ('hobo.agent.common',) + INSTALLED_APPS

    TENANT_APPS = INSTALLED_APPS

    INSTALLED_APPS = ('hobo.multitenant',) + INSTALLED_APPS

    # SAML2: search IdP in <tenant>
    if 'authentic' not in PROJECT_NAME:
        MELLON_ADAPTER = ('hobo.multitenant.mellon.MellonAdapter',)

TEMPLATES[0]['OPTIONS'].setdefault('builtins', []).append('hobo.templatetags.hobo')

if 'authentic' not in PROJECT_NAME:
    MELLON_DEFAULT_ASSERTION_CONSUMER_BINDING = 'artifact'
    MELLON_OPENED_SESSION_COOKIE_NAME = 'A2_OPENED_SESSION'
    MELLON_ADD_AUTHNREQUEST_NEXT_URL_EXTENSION = True

MIDDLEWARE = (
    'hobo.middleware.utils.StoreRequestMiddleware',
    'hobo.middleware.xforwardedfor.XForwardedForMiddleware',
) + MIDDLEWARE


HOBO_MANAGER_HOMEPAGE_URL_VAR = 'portal_agent_url'
HOBO_MANAGER_HOMEPAGE_TITLE_VAR = 'portal_agent_title'

# Locale and timezone
LANGUAGE_CODE = 'fr-fr'
TIME_ZONE = 'Europe/Paris'
LANGUAGES = (('fr', 'Fran\xe7ais'),)
USE_L10N = True
USE_TZ = True

# Celery configuration
BROKER_URL = 'amqp://'
BROKER_TASK_EXPIRES = 600

STATICS_HASH_COUNTER = '/var/lib/publik/statics-counter'

# Django Rest Framework: allow Publik-signed URLs and APIClient
if 'rest_framework' in INSTALLED_APPS:
    if 'REST_FRAMEWORK' not in globals():
        REST_FRAMEWORK = {}
    if 'authentic' not in PROJECT_NAME:
        REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = (
            'hobo.rest_authentication.PublikAuthentication',
            'hobo.rest_authentication.APIClientAuthentication',
        )
    else:
        REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = ('hobo.rest_authentication.PublikAuthentication',)
    REST_FRAMEWORK['DEFAULT_PERMISSION_CLASSES'] = ('rest_framework.permissions.IsAuthenticated',)
    REST_FRAMEWORK['DEFAULT_RENDERER_CLASSES'] = ('rest_framework.renderers.JSONRenderer',)

HOBO_ANONYMOUS_SERVICE_USER_CLASS = 'hobo.rest_authentication.AnonymousAdminServiceUser'

THEMES_DIRECTORY = '/usr/share/publik/themes/'

# xforwardedfor middleware configuration
# create request.META['REMOTE_ADDR'] from X-Forwarded-For header
USE_X_FORWARDED_FOR = True
# headers to be used (only ('X-Forwarded-For',) if empty)
USE_X_FORWARDED_FOR_HEADERS = ('X-Real-IP', 'X-Forwarded-For')

EMAIL_BACKEND = 'hobo.emails.backend.EmailBackend'

# WELL_KNOWN : dict of /.well-known/ files
# WELL_KNOWN  = {
#     'assetlinks.json': {
#        'content': [{
#          'relation': ['delegate_permission/common.handle_all_urls'],
#          'target': { ...
#     },
#     'security.txt': "Contact: mailto:security@....\nExpires: ....\n"
# }
WELL_KNOWN = {}

# Timeout in seconds for the harakiri middleware
HARAKIRI = 0
