#  (c) cavaliba.com - core - settings.py

import os
from pathlib import Path

from celery.schedules import crontab
from django.contrib.messages import constants as messages
from django.core.management.utils import get_random_secret_key

# -------------------------------------------------------------------
# Cavaliba
# -------------------------------------------------------------------

CAVALIBA_VERSION = "4.0.1"

# max supported cavctl version
CAVALIBA_CAVCTL_VERSION = "1.8.0"

TRUE_LIST = ("on", "On", "ON", True, "yes", "Yes", "YES", "True", "true", "TRUE", 1, "1")


# -------------------------------------------------------------------
# Misc
# -------------------------------------------------------------------

# /path/to/source
# /app
BASE_DIR = Path(__file__).resolve().parent.parent


SECRET_KEY = os.environ.get("CAVALIBA_SECRET_KEY", default=get_random_secret_key())
# DEBUG = True
DEBUG = int(os.environ.get("CAVALIBA_DEBUG", default=1))
try:
    ALLOWED_HOSTS = os.environ.get("CAVALIBA_ALLOWED_HOSTS").split(" ")
except Exception:
    ALLOWED_HOSTS = ["*"]

try:
    CSRF_TRUSTED_ORIGINS = os.environ.get("CAVALIBA_CSRF_TRUSTED_ORIGINS").split(" ")
except Exception:
    CSRF_TRUSTED_ORIGINS = [
        "http://localhost:8000",
        "http://192.168.0.11:8000",
        "http://localhost:4180",
    ]


# ENV environnement made available from settings
CAVALIBA_CIPHER_KEY = os.environ.get("CAVALIBA_CIPHER_KEY", None)
CAVALIBA_AUTH_MODE = os.environ.get("CAVALIBA_AUTH_MODE", "local")
CAVALIBA_FORCE_LOGIN = os.environ.get("CAVALIBA_FORCE_LOGIN", "admin")
CAVALIBA_SMS_LOGIN = os.environ.get("CAVALIBA_SMS_LOGIN", "")
CAVALIBA_SMS_PASSWORD = os.environ.get("CAVALIBA_SMS_PASSWORD", "")
CAVALIBA_SMS_URL = os.environ.get("CAVALIBA_SMS_URL", "")
CAVALIBA_DEBUG_AAA = os.environ.get("CAVALIBA_DEBUG_AAA", "no")
CAVALIBA_LAST_LOGIN_MINUTES = int(os.environ.get("CAVALIBA_LAST_LOGIN_MINUTES", "30"))
CAVALIBA_MAX_COMPUTED_USER = int(os.environ.get("CAVALIBA_MAX_COMPUTED_USER", "500"))

# Max SIZE
DATA_UPLOAD_MAX_MEMORY_SIZE = 50000000
FILE_UPLOAD_MAX_MEMORY_SIZE = 50000000

# -------------------------------
# Files / Filestore
# -------------------------------
# global Filer shared beetwen nodes (NFS, ...)
CAVALIBA_FILES = os.environ.get("CAVALIBA_FILES", "./files/")

CAVALIBA_FILESTORE = os.environ.get("CAVALIBA_FILESTORE", Path(CAVALIBA_FILES) / "filestore")
CAVALIBA_EXPORT_FOLDER = os.environ.get("CAVALIBA_EXPORT_FOLDER", Path(CAVALIBA_FILES) / "export")
CAVALIBA_MAIL_FOLDER = os.environ.get("CAVALIBA_MAIL_FOLDER", Path(CAVALIBA_FILES) / "mail")
CAVALIBA_SMS_FOLDER = os.environ.get("CAVALIBA_SMS_FOLDER", Path(CAVALIBA_FILES) / "sms")
CAVALIBA_TEMPLATE_FOLDER = os.environ.get(
    "CAVALIBA_TEMPLATE_FOLDER", Path(CAVALIBA_FILES) / "templates"
)


# -------------------------------------------------------------------
# Application definition
# -------------------------------------------------------------------
SIRENE_APPS = [
    "app_sirene.apps.AppSireneConfig",
    "app_home.apps.AppHomeConfig",
    "app_user.apps.AppUserConfig",
    "app_data.apps.AppDataConfig",
    "app_status.apps.AppStatusConfig",
    "app_ipam.apps.AppIpamConfig",
]

INSTALLED_APPS = SIRENE_APPS + [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "tinymce",
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "django.middleware.locale.LocaleMiddleware",
]

ROOT_URLCONF = "core.urls"

# -------------------------------------------------------------------
# django debug toolbar
# -------------------------------------------------------------------

if DEBUG:
    try:
        import debug_toolbar  # noqa
        import socket  # noqa

        INSTALLED_APPS += ["debug_toolbar"]
        MIDDLEWARE.insert(0, "debug_toolbar.middleware.DebugToolbarMiddleware")

        INTERNAL_IPS = ["127.0.0.1", "::1"]
        hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
        for ip in ips:
            prefix = ip[: ip.rfind(".")]
            INTERNAL_IPS += [f"{prefix}.{i}" for i in range(1, 10)]

        # force activation
        # DEBUG_TOOLBAR_CONFIG = {
        #     "SHOW_TOOLBAR_CALLBACK": lambda request: DEBUG,
        # }
        # print("DJANGO DEBUG TOOLBAR: ON")
    except ImportError:
        # print("DJANGO-DEBUG TOOLBAR: OFF")
        pass


# -------------------------------------------------------------------
# TEMPLATES
# -------------------------------------------------------------------

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        #'DIRS': [ BASE_DIR / 'templates_custom', BASE_DIR / 'templates/'],
        #'DIRS': [ "/app/files/templates/", "/files/templates/", BASE_DIR / 'templates/'],
        "DIRS": [CAVALIBA_TEMPLATE_FOLDER, BASE_DIR / "templates/"],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
                "app_home.context_processor.get_info",  # <-- Add your context processor
            ],
        },
    },
]

WSGI_APPLICATION = "core.wsgi.application"


# -------------------------------------------------------------------
# Database
# -------------------------------------------------------------------

DATABASES = {
    "default": {
        "ENGINE": os.environ.get("CAVALIBA_DB_ENGINE", "django.db.backends.sqlite3"),
        "HOST": os.environ.get("CAVALIBA_DB_HOST", "localhost"),
        "PORT": os.environ.get("CAVALIBA_DB_PORT", 3306),
        "NAME": os.environ.get("CAVALIBA_DB_DATABASE", BASE_DIR / "../db.sqlite3"),
        "USER": os.environ.get("CAVALIBA_DB_USER", "user"),
        "PASSWORD": os.environ.get("CAVALIBA_DB_PASSWORD", "password"),
        "CONN_MAX_AGE": 300,
        "CONN_HEALTH_CHECKS": True,
    }
}

# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"


# -------------------------------
# Cache
# -------------------------------

CAVALIBA_CACHE_CONFIGURATION_TIMEOUT = int(
    os.environ.get("CAVALIBA_CACHE_CONFIGURATION_TIMEOUT", default=60)
)
CAVALIBA_CACHE_SCHEMA_TIMEOUT = int(os.environ.get("CAVALIBA_CACHE_SCHEMA_TIMEOUT", default=60))
CAVALIBA_CACHE_INSTANCE_TIMEOUT = int(os.environ.get("CAVALIBA_CACHE_INSTANCE_TIMEOUT", default=60))
CAVALIBA_CACHE_ENUMERATE_TIMEOUT = int(
    os.environ.get("CAVALIBA_CACHE_ENUMERATE_TIMEOUT", default=120)
)
CAVALIBA_CACHE_DATAPOINT_TIMEOUT = int(
    os.environ.get("CAVALIBA_CACHE_DATAPOINT_TIMEOUT", default=60)
)

CAVALIBA_CACHE_DEFAULT_URL = os.environ.get("CAVALIBA_CACHE_DEFAULT_URL", default="")
CAVALIBA_CACHE_SESSION_URL = os.environ.get("CAVALIBA_CACHE_SESSION_URL", default="")

if CAVALIBA_CACHE_DEFAULT_URL:
    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": CAVALIBA_CACHE_DEFAULT_URL,
            "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
        },
        "session": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": CAVALIBA_CACHE_SESSION_URL or CAVALIBA_CACHE_DEFAULT_URL,
            "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
        },
    }
else:
    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.db.DatabaseCache",
            "LOCATION": "cavaliba_cache_default",
            "TIMEOUT": 3600,
            "OPTIONS": {
                "MAX_ENTRIES": 10000,
            },
        },
        "session": {
            "BACKEND": "django.core.cache.backends.db.DatabaseCache",
            "LOCATION": "cavaliba_cache_session",
            "TIMEOUT": 3600,
            "OPTIONS": {
                "MAX_ENTRIES": 10000,
            },
        },
    }

# -------------------------------
# Sessions
# -------------------------------

# SESSION_ENGINE = 'django.contrib.sessions.backends.db'
SESSION_CACHE_ALIAS = "session"
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_AGE = int(os.environ.get("CAVALIBA_SESSION_DURATION", default=3600))

SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"

# -------------------------------------------------------------------
# Static files (CSS, JavaScript, Images)
# -------------------------------------------------------------------

STATIC_URL = "/static/"

# collectstatic target in Docker mode
STATIC_ROOT = "/static_collect"

# collectstatic source
STATICFILES_DIRS = [
    # highest priority (external)
    BASE_DIR / "files" / "logo",
    # default (internal)
    BASE_DIR / "static",
]


# -------------------------------
# Password validation
# -------------------------------
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
    },
]

# -------------------------------
# Django Login Workflow
# -------------------------------

LOGIN_URL = "/accounts/login"
LOGIN_REDIRECT_URL = "/home/private"


# -------------------------------
# Celery
# -------------------------------

CELERY_BROKER_URL = os.environ.get(
    "CAVALIBA_CELERY_BROKER_URL", default="redis://cavaliba_redis:6379"
)
CELERY_RESULT_BACKEND = os.environ.get(
    "CAVALIBA_CELERY_RESULT_BACKEND", default="redis://cavaliba_redis:6379"
)

# celery(*) or direct
CAVALIBA_TASK_MODE = os.environ.get("CAVALIBA_TASK_MODE", default="celery")
# async(*) or sync
CAVALIBA_TASK_CELERY = os.environ.get("CAVALIBA_TASK_CELERY", default="async")
if CAVALIBA_TASK_CELERY == "sync":
    CELERY_TASK_ALWAYS_EAGER = True


CAVALIBA_HOUSEKEEPING_SCHEDULE = os.environ.get("CAVALIBA_HOUSEKEEPING_SCHEDULE", default="22:22")
try:
    tmp = CAVALIBA_HOUSEKEEPING_SCHEDULE.split(":")
    HOUSEKEEPING_HOUR = int(tmp[0])
    HOUSEKEEPING_MINUTE = int(tmp[1])
except Exception as e:
    print("CAVALIBA HOUSEKEEPING CONFIG ERROR: ", e)
    HOUSEKEEPING_HOUR = 22
    HOUSEKEEPING_MINUTE = 22


# CELERY_CONF_UPDATE = {
#     "enable_utc": False,
#     "timezone": "Europe/Paris",
# }
# CELERY_CONF_TIMEZONE = "Europe/Paris"
CELERY_BEAT_SCHEDULE = {
    # "cron1": {
    #     "task": "core.celery.cron1",
    #     #"schedule": crontab(minute="*/1"),
    #     #'schedule': crontab(hour=7, minute=30, day_of_week=1),
    #     "schedule": 3.0,
    #     "schedule": crontab(hour=19, minute=12),
    #     "args": ("hello",)
    # },
    "housekeeping_daily": {
        "task": "app_home.tasks.housekeeping_daily",
        "schedule": crontab(hour=HOUSEKEEPING_HOUR, minute=HOUSEKEEPING_MINUTE),
    },
    "archive_expired_sirene": {
        "task": "app_sirene.notify.archive_expired_sirene",
        "schedule": 60.0,
    },
    # 3.22 - autogroup cache update
    "iam_autogroup_update": {
        "task": "app_data.tasks.task_autogroup_update",
        "schedule": 120.0,
    },
    "status_run_monitor": {
        "task": "app_status.tasks.task_run_monitor",
        "schedule": 30.0,
    },
    "status_sample_hour": {
        "task": "app_status.tasks.task_sample_hour",
        "schedule": 60.0,
    },
    "status_sample_day": {
        "task": "app_status.tasks.task_sample_day",
        "schedule": 900.0,
    },
    "status_cleanup_raw": {
        "task": "app_status.tasks.task_cleanup_raw",
        "schedule": 900.0,
    },
    "status_cleanup_hour": {
        "task": "app_status.tasks.task_cleanup_hour",
        "schedule": 18000.0,
    },
}


# -------------------------------
# I18N , TZ
# -------------------------------


# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
USE_I18N = True
# LANGUAGE_CODE = 'en-us'
# LANGUAGE_CODE = 'fr-FR'
LANGUAGE_CODE = os.environ.get("CAVALIBA_LANGUAGE_CODE", default="en-us")
# print("CAVALIBA LANGUAGE CODE: ", LANGUAGE_CODE)

USE_TZ = True
# TIME_ZONE = 'UTC'
# TIME_ZONE = 'Europe/Paris'
TIME_ZONE = os.environ.get("CAVALIBA_TIME_ZONE", default="Europe/Paris")
# print("CAVALIBA TIME ZONE: ", TIME_ZONE)


# -------------------------------------------------------------------
# Logging
# -------------------------------------------------------------------

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "simple": {
            "format": "{levelname} {name} {message}",
            "style": "{",
        },
        "verbose": {
            "format": "{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}",
            "style": "{",
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "simple",
            "level": "DEBUG",
        },
        "cavaliba": {
            "class": "app_home.loghandler.CavalibaLogHandler",
            "formatter": "verbose",
            "level": "DEBUG",
        },
        # "file": {
        #         "level": "DEBUG",
        #         "class": "logging.FileHandler",
        #         "filename": "/tmp/debug.log",
        #     },
    },
    # "root": {
    #     "handlers": ["cavaliba"],
    #     "level": "DEBUG",
    # },
    "loggers": {
        "": {
            "handlers": ["console", "cavaliba"],
            "level": "DEBUG",
            "propagate": True,
        },
        "celery": {
            "handlers": ["console"],
            "level": "INFO",
            "propagate": True,
        },
        # 'management_commands': {
        #     'handlers': ['console'],
        #     'level': 'INFO',
        #     'propagate': True,
        # },
        # "app_data.data": {
        #     "handlers": ["console"],
        #     "level": "INFO",
        # },
    },
}

# -------------------------------------------------------------------
# Flash message
# -------------------------------------------------------------------

# from django.contrib.messages import constants as messages

MESSAGE_TAGS = {
    messages.DEBUG: "alert-info",
    messages.INFO: "alert-info",
    messages.SUCCESS: "alert-success",
    messages.WARNING: "alert-warning",
    messages.ERROR: "alert-danger",
}

# -------------------------------------------------------------------
# translation files
# -------------------------------------------------------------------

# LOCALE_PATHS = [
#     BASE_DIR / "locale",
# ]

# -------------------------------------------------------------------
# fixture
# -------------------------------------------------------------------
FIXTURE_DIRS = [
    BASE_DIR / "fixture",
]


# -------------------------------------------------------------------
# TinyMCE
# -------------------------------------------------------------------

# TINYMCE_JS_URL (default: settings.STATIC_URL + 'tinymce/tinymce.min.js')
# The URL of the TinyMCE javascript file:
# TINYMCE_JS_URL = os.path.join(STATIC_URL, "path/to/tiny_mce/tiny_mce.js")


TINYMCE_DEFAULT_CONFIG = {
    "theme": "silver",
    "height": 500,
    "menubar": False,
    "plugins": "advlist,autolink,lists,link,image,charmap,print,preview,anchor,"
    "searchreplace,visualblocks,code,fullscreen,insertdatetime,media,table,paste,"
    "code,help,wordcount",
    "toolbar": "undo redo | formatselect | link |"
    "bold italic backcolor | alignleft aligncenter "
    "alignright alignjustify | bullist numlist outdent indent | "
    "removeformat | code | preview | help",
    "relative_urls": 0,
    "remove_script_host": 0,
    # "setup": "function (editor) {editor.on('change', function () {tinymce.triggerSave();});}",
}

TINYMCE_COMPRESSOR = False
TINYMCE_SPELLCHECKER = False
TINYMCE_FILEBROWSER = False

# -------------------------------------------------------------------
# SIRENE EMAIL GENERAL SETUP
# -------------------------------------------------------------------

EMAIL_HOST = os.environ.get("CAVALIBA_EMAIL_HOST", default="localhost")
EMAIL_PORT = int(os.environ.get("CAVALIBA_EMAIL_PORT", default=25))
EMAIL_HOST_USER = os.environ.get("CAVALIBA_EMAIL_USER", "")
EMAIL_HOST_PASSWORD = os.environ.get("CAVALIBA_EMAIL_PASSWORD", "")

if EMAIL_PORT == 465:
    EMAIL_USE_SSL = True

if EMAIL_PORT == 587:
    EMAIL_USE_TLS = True


# -------------------------------------------------------------------
# in test mode (unittest)
# -------------------------------------------------------------------
# activate if no fixtures in tests
TEST_RUNNER = "core.test_runner.CavalibaTestRunner"
