"""
Django settings for core project.
"""

import os

from configurations import Configuration
from configurations import values

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


class Base(Configuration):
    """
    Base settings.
    """

    # pylint: disable=W0232
    DEBUG = False
    FRONTEND = False
    PRODUCTION = False

    SECRET_KEY = "very-insecure-token"

    DJANGO_APPS = [
        "django.contrib.admin",
        "django.contrib.auth",
        "django.contrib.contenttypes",
        "django.contrib.sessions",
        "django.contrib.sites",
        "django.contrib.messages",
        "django.contrib.staticfiles",
    ]
    THIRD_PARTY_APPS = [
        "allauth",
        "allauth.account",
        "anymail",
        "channels",
        "django_extensions",
        "django_q",
        "health_check",
        "health_check.db",
        "health_check.cache",
        "health_check.storage",
        "health_check.contrib.migrations",
        "storages",
        "widget_tweaks",
        "reversion",
        "rest_framework",
        "rest_framework.authtoken",
        "social_django",
        "corsheaders",
    ]
    LOCAL_APPS = [
        "cards",
        "chat",
        "ecapp",
        "feed",
        "pages",
        "users",
        "usuarios",
        "utils",
    ]

    INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS

    # Application definition

    MIDDLEWARE = [
        "django.middleware.security.SecurityMiddleware",
        "whitenoise.middleware.WhiteNoiseMiddleware",
        "django.contrib.sessions.middleware.SessionMiddleware",
        "corsheaders.middleware.CorsMiddleware",
        "django.middleware.locale.LocaleMiddleware",
        "django.middleware.common.CommonMiddleware",
        "django.middleware.csrf.CsrfViewMiddleware",
        "django.contrib.auth.middleware.AuthenticationMiddleware",
        "django.contrib.messages.middleware.MessageMiddleware",
        "django.middleware.clickjacking.XFrameOptionsMiddleware",
        "reversion.middleware.RevisionMiddleware",
        "social_django.middleware.SocialAuthExceptionMiddleware",
    ]

    REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES": [
            "rest_framework.authentication.TokenAuthentication",
            "rest_framework.authentication.SessionAuthentication",
        ],
        "DEFAULT_PAGINATION_CLASS": "ecapp.pagination.StandardResultsSetPagination",  # noqa: E501 pylint: disable=C0301
    }

    ROOT_URLCONF = "core.urls"

    TEMPLATES = [
        {
            "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",
                    "django_settings_export.settings_export",
                    "social_django.context_processors.backends",
                    "social_django.context_processors.login_redirect",
                ],
            },
        },
    ]

    WSGI_APPLICATION = "core.wsgi.application"
    ASGI_APPLICATION = "core.routing.application"

    SITE_ID = 1

    CORS_ORIGIN_ALLOW_ALL = True
    CORS_ALLOW_CREDENTIALS = True

    DATABASES = values.DatabaseURLValue()
    CACHES = values.CacheURLValue()

    Q_CLUSTER = {
        "timeout": 180,
        "retry": 190,
        "django_redis": "default",
        "error_reporter": {},
    }

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

    AUTH_PASSWORD_VALIDATORS = [
        {
            "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",  # noqa: E501 pylint: disable=C0301
        },
        {
            "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",  # noqa: E501 pylint: disable=C0301
        },
        {
            "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",  # noqa: E501 pylint: disable=C0301
        },
        {
            "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",  # noqa: E501 pylint: disable=C0301
        },
    ]

    AUTHENTICATION_BACKENDS = (
        "django.contrib.auth.backends.ModelBackend",
        "allauth.account.auth_backends.AuthenticationBackend",
        "social_core.backends.twitter.TwitterOAuth",
        "social_core.backends.linkedin.LinkedinOAuth2",
        "social_core.backends.instagram.InstagramOAuth2",
    )

    AUTH_USER_MODEL = "users.User"

    SOCIAL_AUTH_RAISE_EXCEPTIONS = False

    ACCOUNT_EMAIL_REQUIRED = True
    ACCOUNT_USERNAME_REQUIRED = False
    ACCOUNT_AUTHENTICATION_METHOD = "username_email"

    LOGIN_URL = "users:login"
    LOGIN_REDIRECT_URL = "pages:index"
    LOGOUT_URL = "logout"
    LOGOUT_REDIRECT_URL = "pages:index"

    # Internationalization

    LANGUAGES = [
        ("en", "English"),
        ("es", "Español"),
    ]

    LANGUAGE_CODE = "en"

    TIME_ZONE = "America/Mexico_City"

    USE_I18N = True

    USE_L10N = True

    USE_TZ = True

    LOCALE_PATHS = [
        os.path.join(BASE_DIR, "locale"),
    ]
    # Static files (CSS, JavaScript, Images)

    STATICFILES_DIRS = [os.path.join(BASE_DIR, "assets")]

    STATIC_LOCATION = "static"
    STATIC_URL = "/static/"
    STATIC_ROOT = os.path.join(BASE_DIR, "static")

    MEDIA_URL = values.URLValue("http://localhost:8080/media/")
    MEDIA_ROOT = os.path.join(BASE_DIR, "media")

    # Instrumentation

    SETTINGS_EXPORT = ["DEBUG", "PRODUCTION", "FRONTEND"]

    @classmethod
    def setup(cls):
        # pylint: disable=C0103
        REDIS_URL = values.Value(environ_name="CACHE_URL", environ_prefix=None)

        super().setup()

        cls.CHANNEL_LAYERS = {
            "default": {
                "BACKEND": "channels_redis.core.RedisChannelLayer",
                "CONFIG": {
                    "hosts": [REDIS_URL],
                    "symmetric_encryption_keys": [cls.SECRET_KEY],
                },
            },
        }


class Dev(Base):
    """
    Development settings.
    """

    # pylint: disable=W0232
    DEBUG = True
    FRONTEND = True

    EMAIL_BACKEND = "mail_panel.backend.MailToolbarBackend"

    INSTALLED_APPS = Base.INSTALLED_APPS + [
        "debug_toolbar",
        "mail_panel",
    ]

    MIDDLEWARE = [
        "debug_toolbar.middleware.DebugToolbarMiddleware",
    ] + Base.MIDDLEWARE

    DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda request: True}

    DEBUG_TOOLBAR_PANELS = [
        "debug_toolbar.panels.history.HistoryPanel",
        "debug_toolbar.panels.versions.VersionsPanel",
        "debug_toolbar.panels.timer.TimerPanel",
        "debug_toolbar.panels.settings.SettingsPanel",
        "mail_panel.panels.MailToolbarPanel",
        "debug_toolbar.panels.headers.HeadersPanel",
        "debug_toolbar.panels.request.RequestPanel",
        "debug_toolbar.panels.sql.SQLPanel",
        "debug_toolbar.panels.staticfiles.StaticFilesPanel",
        "debug_toolbar.panels.templates.TemplatesPanel",
        "debug_toolbar.panels.cache.CachePanel",
        "debug_toolbar.panels.signals.SignalsPanel",
        "debug_toolbar.panels.logging.LoggingPanel",
        "debug_toolbar.panels.redirects.RedirectsPanel",
        "debug_toolbar.panels.profiling.ProfilingPanel",
    ]

    ALLOWED_HOSTS = ["*"]


class Testing(Base):
    """
    Testing settings.
    """

    # pylint: disable=W0232
    DATABASES = values.DatabaseURLValue(
        "sqlite://:memory:",
        environ_name="TESTING_DATABASE_URL",
    )
    EMAIL = values.EmailURLValue("memory://", environ_name="TESTING_EMAIL_URL")
    CACHES = values.CacheURLValue(
        "locmem://",
        environ_name="TESTING_CACHE_URL",
    )


class IntegrationTesting(Base):
    """
    Integration testing settings.
    """

    # pylint: disable=W0232
    ALLOWED_HOSTS = ["*"]

    CACHES = values.CacheURLValue("locmem://")
    Q_CLUSTER = {
        "workers": 1,
        "timeout": 90,
        "retry": 100,
        "orm": "default",
        "sync": True,
        "scheduler": False,
    }

    EMAIL = values.EmailURLValue()
    DEFAULT_FROM_EMAIL = "mail@example.com"

    STATIC_URL = values.URLValue("http://localhost:8080/static/")
    MEDIA_URL = values.URLValue("http://localhost:8080/media/")


class Production(Base):
    """
    Production settings.
    """

    # pylint: disable=W0232
    PRODUCTION = True
    ALLOWED_HOSTS = values.ListValue()
    SECRET_KEY = values.SecretValue()

    SITE_ID = values.IntegerValue(1)

    STATICFILES_STORAGE = (
        "whitenoise.storage.CompressedManifestStaticFilesStorage"
    )

    # Social auth LinkedIn
    SOCIAL_AUTH_LINKEDIN_OAUTH2_KEY = values.SecretValue()
    SOCIAL_AUTH_LINKEDIN_OAUTH2_SECRET = values.SecretValue()
    SOCIAL_AUTH_LINKEDIN_OAUTH2_SCOPE = ["r_liteprofile", "r_emailaddress"]
    SOCIAL_AUTH_LINKEDIN_OAUTH2_FIELD_SELECTORS = [
        "email-address",
        "formatted-name",
        "public-profile-url",
        "picture-url",
    ]
    SOCIAL_AUTH_LINKEDIN_OAUTH2_EXTRA_DATA = [
        ("id", "id"),
        ("formattedName", "name"),
        ("emailAddress", "email_address"),
        ("pictureUrl", "picture_url"),
        ("publicProfileUrl", "profile_url"),
    ]

    # Social auth Twitter
    SOCIAL_AUTH_TWITTER_KEY = values.SecretValue()
    SOCIAL_AUTH_TWITTER_SECRET = values.SecretValue()

    DEFAULT_FROM_EMAIL = values.SecretValue()
    SERVER_EMAIL = values.SecretValue()

    # Set email configuration
    # EMAIL_BACKEND = "anymail.backends.service"
    EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
    EMAIL_HOST = values.SecretValue()
    EMAIL_HOST_PASSWORD = values.SecretValue()
    EMAIL_HOST_USER = values.SecretValue()
    EMAIL_HOST_PORT = values.SecretValue()
