"""
Django settings for servala project.

Servala is run using environment variables. Documentation:

- README.md for project information
- .env.example for environment variables in use
- Django settings guide: https://docs.djangoproject.com/en/5.2/topics/settings/
- Django settings reference: https://docs.djangoproject.com/en/5.2/ref/settings/
"""

import os
from pathlib import Path

import sentry_sdk
from django.contrib import messages
from sentry_sdk.integrations.django import DjangoIntegration

from servala.__about__ import __version__ as version

SERVALA_ENVIRONMENT = os.environ.get("SERVALA_ENVIRONMENT", "development")
DEBUG = SERVALA_ENVIRONMENT == "development"
SERVALA_SHOW_BETA_BANNER = os.environ.get("SERVALA_SHOW_BETA_BANNER", "True") == "True"

SECRET_KEY = os.environ.get("SERVALA_SECRET_KEY")
if previous_secret_key := os.environ.get("SERVALA_PREVIOUS_SECRET_KEY"):
    SECRET_KEY_FALLBACKS = [previous_secret_key]

SALT_KEY = os.environ.get("SERVALA_SALT_KEY")
if previous_salt := os.environ.get("SERVALA_PREVIOUS_SALT_KEY"):
    SALT_KEY = [SALT_KEY, previous_salt]

BASE_DIR = Path(__file__).resolve().parent.parent

ALLOWED_HOSTS = []
if allowed_hosts := os.environ.get("SERVALA_ALLOWED_HOSTS"):
    ALLOWED_HOSTS = allowed_hosts.split(",")
    CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in ALLOWED_HOSTS]

db_name = os.environ.get("SERVALA_DB_NAME", "")
if SERVALA_ENVIRONMENT == "development" and not db_name:
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.sqlite3",
            "NAME": BASE_DIR / "db.sqlite3",
            "OPTIONS": {"timeout": 10},
        }
    }
else:
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.postgresql",
            "NAME": db_name or "servala",
            "USER": os.environ.get("SERVALA_DB_USER", "servala"),
            "PASSWORD": os.environ.get("SERVALA_DB_PASSWORD"),
            "HOST": os.environ.get("SERVALA_DB_HOST", "localhost"),
            "PORT": os.environ.get("SERVALA_DB_PORT", "5432"),
            "CONN_MAX_AGE": 120,
            "CONN_HEALTH_CHECKS": True,
        }
    }

MEDIA_ROOT = os.environ.get("SERVALA_MEDIA_ROOT", "media")

if MEDIA_ROOT.startswith("/"):
    MEDIA_ROOT = Path(MEDIA_ROOT)
else:
    MEDIA_ROOT = BASE_DIR / MEDIA_ROOT

EMAIL_HOST = os.environ.get("SERVALA_EMAIL_HOST", "localhost")
EMAIL_PORT = int(os.environ.get("SERVALA_EMAIL_PORT", "25"))
EMAIL_HOST_USER = os.environ.get("SERVALA_EMAIL_USER", "")
EMAIL_HOST_PASSWORD = os.environ.get("SERVALA_EMAIL_PASSWORD", "")
EMAIL_USE_TLS = os.environ.get("SERVALA_EMAIL_TLS", "False") == "True"
EMAIL_USE_SSL = os.environ.get("SERVALA_EMAIL_SSL", "False") == "True"
EMAIL_DEFAULT_FROM = os.environ.get("SERVALA_EMAIL_DEFAULT_FROM", "noreply@servala.com")

SERVALA_DEFAULT_ORIGIN = int(os.environ.get("SERVALA_DEFAULT_ORIGIN", "1"))

OSB_USERNAME = os.environ.get("SERVALA_OSB_USERNAME")
OSB_PASSWORD = os.environ.get("SERVALA_OSB_PASSWORD")

SOCIALACCOUNT_PROVIDERS = {
    "openid_connect": {
        "APPS": [
            {
                "provider_id": "keycloak",
                "name": "VSHN Account",
                "client_id": os.environ.get("SERVALA_KEYCLOAK_CLIENT_ID"),
                "secret": os.environ.get("SERVALA_KEYCLOAK_CLIENT_SECRET"),
                "settings": {
                    "server_url": os.environ.get("SERVALA_KEYCLOAK_SERVER_URL"),
                },
            }
        ]
    }
}

SERVALA_STORAGE_BUCKET_NAME = os.environ.get("SERVALA_STORAGE_BUCKET_NAME")
SERVALA_S3_ENDPOINT_URL = os.environ.get("SERVALA_S3_ENDPOINT_URL")
SERVALA_ACCESS_KEY_ID = os.environ.get("SERVALA_ACCESS_KEY_ID")
SERVALA_SECRET_ACCESS_KEY = os.environ.get("SERVALA_SECRET_ACCESS_KEY")
SERVALA_S3_REGION_NAME = os.environ.get("SERVALA_S3_REGION_NAME", "eu-central-1")
SERVALA_S3_ADDRESSING_STYLE = os.environ.get("SERVALA_S3_ADDRESSING_STYLE", "virtual")
SERVALA_S3_SIGNATURE_VERSION = os.environ.get("SERVALA_S3_SIGNATURE_VERSION", "s3v4")

# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html
if all(
    [
        SERVALA_STORAGE_BUCKET_NAME,
        SERVALA_S3_ENDPOINT_URL,
        SERVALA_ACCESS_KEY_ID,
        SERVALA_SECRET_ACCESS_KEY,
    ]
):
    STORAGES = {
        "default": {
            "BACKEND": "storages.backends.s3.S3Storage",
            "OPTIONS": {
                "bucket_name": SERVALA_STORAGE_BUCKET_NAME,
                "endpoint_url": SERVALA_S3_ENDPOINT_URL,
                "access_key": SERVALA_ACCESS_KEY_ID,
                "secret_key": SERVALA_SECRET_ACCESS_KEY,
                "region_name": SERVALA_S3_REGION_NAME,
                "addressing_style": SERVALA_S3_ADDRESSING_STYLE,
                "signature_version": SERVALA_S3_SIGNATURE_VERSION,
            },
        },
        "staticfiles": {
            "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
        },
    }

ODOO = {
    "URL": os.environ.get("SERVALA_ODOO_URL"),
    "DB": os.environ.get("SERVALA_ODOO_DB"),
    "USERNAME": os.environ.get("SERVALA_ODOO_USERNAME"),
    "PASSWORD": os.environ.get("SERVALA_ODOO_PASSWORD"),
    "HELPDESK_TEAM_ID": int(os.environ.get("SERVALA_ODOO_HELPDESK_TEAM_ID", "5")),
}

#######################################
#   Non-configurable settings below   #
#######################################

WSGI_APPLICATION = "servala.wsgi.application"

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # The frontend app is loaded early in order to supersede some allauth views/behaviour
    "servala.frontend",
    "django.forms",
    "django_jsonform",
    "template_partials",
    "rules.apps.AutodiscoverRulesConfig",
    "allauth",
    "allauth.account",
    "allauth.socialaccount",
    "allauth.socialaccount.providers.openid_connect",
    "auditlog",
    "servala.core",
    "servala.api",
]

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",
    "allauth.account.middleware.AccountMiddleware",
    "django.contrib.auth.middleware.LoginRequiredMiddleware",
    "auditlog.middleware.AuditlogMiddleware",
    "servala.core.middleware.OrganizationMiddleware",
]
LOGIN_URL = "account_login"

ROOT_URLCONF = "servala.urls"
STATIC_URL = "static/"  # CSS, JavaScript, etc.
# Collected static files as provided by ``collectstatic`` management command are stored here ready to be served by a web server.
STATIC_ROOT = BASE_DIR / "static.dist"
MEDIA_URL = "media/"  # User uploads, e.g. images

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.db.DatabaseCache",
        "LOCATION": "servala_cache",
    }
}

# Additional locations of static files
STATICFILES_FINDERS = (
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
)
STATICFILES_DIRS = [BASE_DIR / "servala" / "static"]
template_loaders = (
    "django.template.loaders.filesystem.Loader",
    "django.template.loaders.app_directories.Loader",
)
if not DEBUG:
    template_loaders = (("django.template.loaders.cached.Loader", template_loaders),)

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": False,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
                "django.template.context_processors.static",
                "servala.frontend.context_processors.add_organizations",
                "servala.frontend.context_processors.add_beta_banner",
            ],
            "loaders": template_loaders,
        },
    },
]

FORM_RENDERER = "servala.frontend.forms.renderers.VerticalFormRenderer"
MESSAGE_TAGS = {
    messages.ERROR: "danger",
}

AUTH_USER_MODEL = "core.User"
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_LOGIN_METHODS = {"email"}
ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*", "password2*"]
ACCOUNT_SIGNUP_FORM_CLASS = "servala.frontend.forms.auth.ServalaSignupForm"
if ALLOWED_HOSTS or not DEBUG:
    ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"

AUTHENTICATION_BACKENDS = [
    "rules.permissions.ObjectPermissionBackend",
    # Needed to login by username in Django admin, regardless of `allauth`
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend",
]
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"},
]
PASSWORD_HASHERS = [
    "django.contrib.auth.hashers.Argon2PasswordHasher",
    "django.contrib.auth.hashers.PBKDF2PasswordHasher",
    "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
    "django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
    "django.contrib.auth.hashers.ScryptPasswordHasher",
]
CSRF_COOKIE_NAME = "servala_csrf"
LANGUAGE_COOKIE_NAME = "servala_lang"
SESSION_COOKIE_NAME = "servala_sess"
SESSION_COOKIE_SECURE = not DEBUG

DEFAULT_LABEL_KEY = "appcat.vshn.io/provider-config"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# Prefix for auto-generated Kubernetes resource names for service instances
SERVALA_INSTANCE_NAME_PREFIX = os.environ.get("SERVALA_INSTANCE_NAME_PREFIX", "si")

# TODO
TIME_ZONE = "UTC"

if SERVALA_ENVIRONMENT in ("staging", "production"):
    SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

SERVALA_SENTRY_DSN = os.environ.get("SERVALA_SENTRY_DSN")
sentry_sdk.init(
    dsn=SERVALA_SENTRY_DSN,
    integrations=[DjangoIntegration()],
    auto_session_tracking=False,
    traces_sample_rate=0.01,
    release=version,
    environment=SERVALA_ENVIRONMENT,
)
