"""
Django settings for the demo project.

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

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

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

from __future__ import annotations

from typing import Any

import bleach
import environ

# The name of our project
# ------------------------------------------------------------------------------
PROJECT_NAME: str = "demo"
HUMAN_PROJECT_NAME: str = "Wildewidgets Demo"

# Load our environment with django-environ
BASE_DIR: environ.Path = environ.Path(__file__) - 2
APPS_DIR: environ.Path = BASE_DIR.path(PROJECT_NAME)

env: environ.Env = environ.Env()

# ==============================================================================

# DEBUG is Django's own config variable, while DEVELOPMENT is ours.
# Use DEVELOPMENT for things that you want to be able to enable/disable in dev
# without altering DEBUG, since that affects lots of other things.
DEBUG: bool = env.bool("DEBUG", default=False)
DEVELOPMENT: bool = env.bool("DEVELOPMENT", default=False)
DEPLOYFISH_ENVIRONMENT: str = env("DEPLOYFISH_ENVIRONMENT", default="dev")

# GENERAL
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/2.2/ref/settings/#secret-key
SECRET_KEY: str = env("DJANGO_SECRET_KEY", default="CHANGE_ME")
# https://docs.djangoproject.com/en/2.2/ref/settings/#allowed-hosts
ALLOWED_HOSTS: list[str] = env.list("DJANGO_ALLOWED_HOSTS", default=["*"])

# INTERNATIONALIZATION (i18n) AND LOCALIZATION (l10n)
# Change these values to suit this project.
# https://docs.djangoproject.com/en/2.2/topics/i18n/
# ------------------------------------------------------------------------------
LANGUAGE_CODE: str = "en-us"
TIME_ZONE: str = "America/Los_Angeles"
USE_I18N: bool = False
USE_L10N: bool = False
USE_TZ: bool = True

# DATABASES
# -----------
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
if env("TESTING", default=False):
    DATABASES: dict[str, dict[str, Any]] = {
        "default": {
            "ENGINE": "django.db.backends.sqlite3",
            "NAME": BASE_DIR.path("db.sqlite3"),
        }
    }
else:
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",
            "NAME": env("DB_NAME", default="demo"),
            "USER": env("DB_USER", default="demo_u"),
            "PASSWORD": env("DB_PASSWORD", default="password"),
            "HOST": env("DB_HOST", default="db"),
            "ATOMIC_REQUESTS": True,
            "CONN_MAX_AGE": env.int("CONN_MAX_AGE", default=60),
            # This is needed in case the database doesn't have the newer default
            # settings that enable "strict mode".
            "OPTIONS": {
                "sql_mode": "traditional",
            },
        }
    }
DEFAULT_AUTO_FIELD: str = "django.db.models.AutoField"


# URLS
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/2.2/ref/settings/#root-urlconf
# noinspection PyUnresolvedReferences
ROOT_URLCONF: str = f"{PROJECT_NAME}.urls"
# https://docs.djangoproject.com/en/2.2/ref/settings/#wsgi-application
WSGI_APPLICATION: str = f"{PROJECT_NAME}.wsgi.application"

# APPS
# ------------------------------------------------------------------------------
DJANGO_APPS: list[str] = [
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # 'django.contrib.humanize', # Handy template tags
    "django.contrib.admin",
]
THIRD_PARTY_APPS: list[str] = [
    "storages",
    # 'django_js_reverse',
    "django_extensions",
    "chartjs",
    "wildewidgets",
    "markdownify",
    "book_manager",
    "crispy_forms",
    "crispy_bootstrap5",
    "academy_theme",
    "sass_processor",
]
LOCAL_APPS: list[str] = [
    f"{PROJECT_NAME}.core",
    f"{PROJECT_NAME}.users",
]
# https://docs.djangoproject.com/en/2.2/ref/settings/#installed-apps
INSTALLED_APPS: list[str] = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS

# AUTHENTICATION
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/3.2/ref/settings/#authentication-backends
AUTHENTICATION_BACKENDS: list[str] = [
    "django.contrib.auth.backends.ModelBackend",
]

# Use our custom User model instead of auth.User, because it's good practice to
# define a custom one at the START.
AUTH_USER_MODEL: str = "users.User"

# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS: list[dict[str, str]] = [
    {
        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"  # noqa: E501
    },
    {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
    {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
    {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]

# MIDDLEWARE
# ------------------------------------------------------------------------

MIDDLEWARE: list[str] = [
    # Django's "default" middleware, in the appropriate order according to
    # Django 2.0 docs.
    "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",
    # Set our REMOTE_ADDR properly when we're behind a proxy.
    "xff.middleware.XForwardedForMiddleware",
    # Enables the use of the get_current_request() and get_current_user() functions.
    "crequest.middleware.CrequestMiddleware",
]

# STATIC
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/2.2/ref/settings/#static-root
STATIC_ROOT: str = "/static"
# https://docs.djangoproject.com/en/2.2/ref/settings/#static-url
STATIC_URL: str = f"/static/{PROJECT_NAME}/"
# https://docs.djangoproject.com/en/2.2/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS: list[str] = []
# https://docs.djangoproject.com/en/2.2/ref/contrib/staticfiles/#staticfiles-finders
STATICFILES_FINDERS: list[str] = [
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
]

# MEDIA
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/2.2/ref/settings/#default-file-storage
DEFAULT_FILE_STORAGE: str = "django.core.files.storage.FileSystemStorage"
# https://docs.djangoproject.com/en/2.2/ref/settings/#media-root
# noinspection PyUnresolvedReferences
MEDIA_ROOT: str = "/media"
# https://docs.djangoproject.com/en/2.2/ref/settings/#media-url
MEDIA_URL: str = "/media/"


# TEMPLATES
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/2.2/ref/settings/#templates
# The CACHE_TEMPLATES setting defaults to True, and tells Django to cache the
# template files it reads from disc in RAM.  This radically increases
# performance, especially on docker when using shared volumes to keep your
# up-to-date code in the container, but it also means that the template cache
# sticks around until Gunicorn restarts. This complicates the development
# process for templates, so you are _generally_ recommended to set
# CACHE_TEMPLATES=False in your dev env.  But because it makes _such_ a huge
# difference in docker-shared-volume performance, it's useful to leave it set to
# True when you're not actively doing template development.
CACHE_TEMPLATES: bool = env.bool("CACHE_TEMPLATES", default=True)
TEMPLATES: list[dict[str, Any]] = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "APP_DIRS": True,
        "OPTIONS": {
            # Django does template caching for us correctly as long as
            # OPTIONS['debug'] is False.
            "debug": not CACHE_TEMPLATES,
            # https://docs.djangoproject.com/en/2.2/ref/settings/#template-loaders
            # https://docs.djangoproject.com/en/2.2/ref/templates/api/#loader-types
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.template.context_processors.i18n",
                "django.template.context_processors.static",
                "django.template.context_processors.tz",
                "django.contrib.messages.context_processors.messages",
                "academy_theme.context_processors.theme",
            ],
        },
    },
]

# FIXTURES
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/2.2/ref/settings/#fixture-dirs
FIXTURE_DIRS: tuple[str, ...] = (str(APPS_DIR.path("fixtures")),)

MARKDOWNIFY: dict[str, dict[str, Any]] = {
    "default": {
        "WHITELIST_TAGS": [*bleach.sanitizer.ALLOWED_TAGS, "p", "h1", "h2", "pre"]
    },
}

CRISPY_ALLOWED_TEMPLATE_PACKS: str = "bootstrap5"
CRISPY_TEMPLATE_PACK: str = "bootstrap5"

ACADEMY_THEME_SETTINGS: dict[str, Any] = {
    # Header
    "APPLE_TOUCH_ICON": "myapp/images/apple-touch-icon.png",
    "FAVICON_32": "myapp/images/favicon-32x32.png",
    "FAVICON_16": "myapp/images/favicon-16x16.png",
    "FAVICON": "myapp/images/favicon.ico",
    "SITE_WEBMANIFEST": "myapp/images/site.webmanifest",
    # Footer
    "ORGANIZATION_LINK": "https://caltech.edu",
    "ORGANIZATION_NAME": "Academic Development Services",
    "ORGANIZATION_ADDRESS": "",
    "COPYRIGHT_ORGANIZATION": "California Institute of Technology",
    "FOOTER_LINKS": [],
}
