"""
Django settings for marinerg_tap project.

Generated by 'django-admin startproject' using Django 5.1.

For more information on this file, see
https://docs.djangoproject.com/en/5.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.1/ref/settings/
"""

from pathlib import Path
import os

from corsheaders.defaults import default_headers

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/

secret_key_env = os.environ.get("DJANGO_SECRET_KEY")
if not secret_key_env:
    raise RuntimeError("No DJANGO_SECRET_KEY key set in environment")
SECRET_KEY = secret_key_env.replace('"', "")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = bool(os.environ.get("DJANGO_DEBUG", default=0))

ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", default="*").split(",")

ADMIN_URL = os.environ.get("DJANGO_ADMIN_URL", default="admin")

API_AUTH_URL = os.environ.get("DJANGO_API_AUTH_URL", default="api-auth")

# OIDC Connection
WITH_OIDC = bool(os.environ.get("WITH_OIDC", default=0))
OIDC_RP_CLIENT_ID = os.environ.get("OIDC_RP_CLIENT_ID")
OIDC_RP_CLIENT_SECRET = os.environ.get("OIDC_RP_CLIENT_SECRET")
OIDC_RP_SIGN_ALGO = "RS256"
OIDC_USE_PKCE = True
OIDC_OP_AUTHORIZATION_ENDPOINT = os.environ.get("OIDC_OP_AUTHORIZATION_ENDPOINT")
OIDC_OP_TOKEN_ENDPOINT = os.environ.get("OIDC_OP_TOKEN_ENDPOINT")
OIDC_OP_USER_ENDPOINT = os.environ.get("OIDC_OP_USER_ENDPOINT")
OIDC_OP_JWKS_ENDPOINT = os.environ.get("OIDC_OP_JWKS_ENDPOINT")
OIDC_USERNAME_ALGO = "ichec_django_core.auth.backends.generate_username"

# SECURITY WARNING: This is meant just for local development - it will allow ANY user to
# create an account on the portal. Use a suitable third-party
# user management tool/IDP (e.g. Keycloak) in production.
WITH_USER_LOGIN = bool(os.environ.get("DJANGO_WITH_USER_LOGIN", default=0))

# If a new user is created during login - e.g. from OIDC they will be
# automatically added to this group
AUTO_ASSIGNED_USER_GROUP = os.environ.get("DJANGO_AUTO_ASSIGNED_USER_GROUP")

# If true users created by fixtures or the admin portal are automatically marked
# as verified. In production you likely want this to be false.
AUTO_VERIFY_USERS = bool(os.environ.get("DJANGO_AUTO_VERIFY_USERS", default=0))

# Switch to enable soft deleting on supported models.
SOFT_DELETE = bool(os.environ.get("DJANGO_SOFT_DELETE", default=1))

# Application definition
INSTALLED_APPS = [
    "ichec_django_core.apps.IchecDjangoCoreConfig",
    "rest_framework",
    "corsheaders",
    "django_countries",
    "django_prometheus",
    "django_filters",
    "rest_framework.authtoken",
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
]

if WITH_OIDC:
    INSTALLED_APPS.append("mozilla_django_oidc")
    LOGIN_REDIRECT_URL = os.environ.get("LOGIN_REDIRECT_URL", default="/")
    LOGOUT_REDIRECT_URL = os.environ.get("OIDC_LOGOUT_REDIRECT_URL", default="/")

WITH_VERBOSE_LOGGING = os.environ.get("DJANGO_APP_VERBOSE_LOGGING", default=False)

WITH_METRICS = os.environ.get("DJANGO_WITH_METRICS", default=False)

MIDDLEWARE = []
if WITH_VERBOSE_LOGGING:
    MIDDLEWARE.append("ichec_django_core.middleware.RequestLoggerMiddleware")

if WITH_METRICS:
    MIDDLEWARE.append("django_prometheus.middleware.PrometheusBeforeMiddleware")

MIDDLEWARE.extend(
    [
        "django.middleware.security.SecurityMiddleware",
        "django.contrib.sessions.middleware.SessionMiddleware",
        "corsheaders.middleware.CorsMiddleware",
        "django.middleware.common.CommonMiddleware",
        "django.middleware.csrf.CsrfViewMiddleware",
        "django.contrib.auth.middleware.AuthenticationMiddleware",
        "django.contrib.messages.middleware.MessageMiddleware",
        "django.middleware.clickjacking.XFrameOptionsMiddleware",
    ]
)

if WITH_OIDC:
    MIDDLEWARE.append("ichec_django_core.middleware.oidc.RefreshOIDCAccessToken")

if WITH_METRICS:
    MIDDLEWARE.append("django_prometheus.middleware.PrometheusAfterMiddleware")

if WITH_VERBOSE_LOGGING:
    MIDDLEWARE.append("ichec_django_core.middleware.RequestLoggerMiddleware")

# Auth
AUTHENTICATION_BACKENDS = ["django.contrib.auth.backends.ModelBackend"]
if WITH_OIDC:
    AUTHENTICATION_BACKENDS = [
        "ichec_django_core.auth.backends.MemberOIDCAuthenticationBackend"
    ] + AUTHENTICATION_BACKENDS

ROOT_URLCONF = "app.urls"


def get_templates(base_dir: Path):
    return [
        {
            "BACKEND": "django.template.backends.django.DjangoTemplates",
            "DIRS": [os.path.join(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",
                ],
            },
        },
    ]


TEMPLATES = get_templates(BASE_DIR)

WSGI_APPLICATION = "app.wsgi.application"


# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases


def get_databases(base_dir: Path):
    return {
        "default": {
            "ENGINE": os.environ.get("DJANGO_SQL_ENGINE", "django.db.backends.sqlite3"),
            "NAME": os.environ.get("DJANGO_SQL_DATABASE", base_dir / "db.sqlite3"),
            "USER": os.environ.get("DJANGO_SQL_USER", "user"),
            "PASSWORD": os.environ.get("DJANGO_SQL_PASSWORD", "password"),
            "HOST": os.environ.get("DJANGO_SQL_HOST", "localhost"),
            "PORT": os.environ.get("DJANGO_SQL_PORT", "5432"),
        }
    }


DATABASES = get_databases(BASE_DIR)


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

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


# Internationalization
# https://docs.djangoproject.com/en/5.1/topics/i18n/

LANGUAGE_CODE = "en-us"

TIME_ZONE = "UTC"

USE_I18N = True

USE_TZ = True

SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/

STATIC_URL = "static/"


def get_static_root(base_dir: Path):
    return Path(os.environ.get("DJANGO_STATIC_ROOT", default=base_dir / "staticfiles"))


STATIC_ROOT = get_static_root(BASE_DIR)


def get_media_root(base_dir: Path):
    return Path(os.environ.get("DJANGO_MEDIA_ROOT", default=base_dir / "mediafiles"))


MEDIA_ROOT = get_media_root(BASE_DIR)

DEFAULT_FILE_STORAGE = "django_downloadview.storage.SignedStorage"
DOWNLOADVIEW_BACKEND = "django_downloadview.nginx.XAccelRedirectMiddleware"

DOWNLOADVIEW_RULES = [
    {
        "source_url": "/media/nginx/",
        "destination_url": "/nginx-optimized-by-middleware/",
    },
]

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

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

DRF_AUTH_CLASSES = []
if WITH_OIDC:
    DRF_AUTH_CLASSES.append("mozilla_django_oidc.contrib.drf.OIDCAuthentication")
DRF_AUTH_CLASSES.extend(
    [
        "rest_framework.authentication.TokenAuthentication",
        "rest_framework.authentication.SessionAuthentication",
    ]
)

REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
    "DEFAULT_FILTER_BACKENDS": ("django_filters.rest_framework.DjangoFilterBackend",),
    "DEFAULT_AUTHENTICATION_CLASSES": DRF_AUTH_CLASSES,
    "DEFAULT_PAGINATION_CLASS": "ichec_django_core.views.pagination.PageNumberWithSizePagination",  # NOQA
    "PAGE_SIZE": 100,
}

if DEBUG:
    CORS_ALLOWED_ORIGINS = ["http://localhost:4200", "http://127.0.0.1:4200"]

    # Below is to allow Cross site setting of the credential cookies
    # Use it only in Debug mode for development.
    CORS_ALLOW_CREDENTIALS = True
    CSRF_COOKIE_SAMESITE = "Lax"
    SESSION_COOKIE_SAMESITE = "Lax"
    CSRF_TRUSTED_ORIGINS = ["http://localhost:4200"]
    CORS_ALLOW_HEADERS = [*default_headers, "Content-Disposition"]
    CORS_EXPOSE_HEADERS = ["Content-Disposition", "Content-Type", "X-CSRFToken"]
else:
    CSRF_COOKIE_SAMESITE = "Strict"
    CSRF_COOKIE_SECURE = True
    SESSION_COOKIE_SAMESITE = "Strict"
    SESSION_COOKIE_HTTPONLY = True
    SESSION_COOKIE_SECURE = True

if False:
    EMAIL_HOST_USER = "Test User"
    EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
    EMAIL_FILE_PATH = os.getcwd() + "/app-messages"
else:
    EMAIL_HOST = os.environ.get("DJANGO_EMAIL_HOST", default="")
    EMAIL_PORT = os.environ.get("DJANGO_EMAIL_PORT", default="")
    EMAIL_HOST_USER = os.environ.get("DJANGO_EMAIL_HOST_USER", default="")
    EMAIL_HOST_PASSWORD = os.environ.get("DJANGO_EMAIL_HOST_PASSWORD", default="")
    EMAIL_USE_TLS = True

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "root": {
        "handlers": ["console"],
        "level": "DEBUG",
    },
}
