# Copyright 2022 The Debusine Developers
# See the AUTHORS file at the top-level directory of this distribution
#
# This file is part of Debusine. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution. No part of Debusine, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the LICENSE file.
"""Debusine checks using Django checks framework."""
import getpass
import pathlib

from django.conf import settings
from django.core.checks import Error, register


def _check_directories_owners(setting_names, *, missing_ok):
    current_user = getpass.getuser()

    errors = []

    for setting_name in setting_names:
        directory = pathlib.Path(getattr(settings, setting_name))

        if not directory.exists() and missing_ok:
            continue
        elif not directory.exists():
            errors.append(Error(f"{directory} must exist"))
        elif directory.owner() != current_user:
            errors.append(
                Error(
                    f"{directory} owner ({directory.owner()}) must match "
                    f"current user ({current_user})"
                )
            )

    return errors


@register()
def mandatory_directories_check(app_configs, **kwargs):  # noqa: U100
    """Check mandatory directories exist and the owner is the running user."""
    return _check_directories_owners(["DEBUSINE_DATA_PATH"], missing_ok=False)


@register()
def optional_directories_check(app_configs, **kwargs):  # noqa: U100
    """Check optional directories, if they exist, have the correct owner."""
    return _check_directories_owners(
        [
            "STATIC_ROOT",
            "MEDIA_ROOT",
            "DEBUSINE_CACHE_DIRECTORY",
            "DEBUSINE_TEMPLATE_DIRECTORY",
        ],
        missing_ok=True,
    )


@register()
def secret_key_not_default_in_debug_0(app_configs, **kwargs):  # noqa: U100
    """Check SECRET_KEY is not the default if Debug=False (unless testing)."""
    if getattr(settings, "TEST_MODE", False):
        # In Django the tests run with settings.DEBUG = False by design.
        # When testing Debusine it is allowed to use the default SECRET_KEY
        return []

    if not settings.DEBUG and settings.SECRET_KEY.startswith("default:"):
        return [
            Error(
                'Default SECRET_KEY cannot be used in DEBUG=False. Make sure '
                'to use "SECRET_kEY = read_secret_key(path)" from selected.py '
                'settings file',
                hint="Generate a secret key using the command: "
                "$ python3 -c 'from django.core.management.utils import "
                "get_random_secret_key; print(get_random_secret_key())'",
            )
        ]

    return []


@register()
def disable_automatic_scheduling_false_in_production(
    app_configs, **kwargs  # noqa: U100
):
    """Check DISABLE_AUTOMATIC_SCHEDULING is enabled only in TEST_MODE."""
    if getattr(settings, "DISABLE_AUTOMATIC_SCHEDULING", False) and not getattr(
        settings, "TEST_MODE", False
    ):
        return [
            Error(
                "DISABLE_AUTOMATIC_SCHEDULING can only be enabled in TEST_MODE",
                hint="Remove DISABLE_AUTOMATIC_SCHEDULING=True "
                "from debusine-server settings",
            )
        ]

    return []
