# Copyright (c) 2019-2024 Alexander Todorov <atodorov@otb.bg>
#
# Licensed under GNU Affero General Public License v3 or later (AGPLv3+)
# https://www.gnu.org/licenses/agpl-3.0.html

# pylint: disable=too-few-public-methods
from datetime import timedelta

from django.contrib import messages
from django.http import HttpResponseForbidden
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from tcms_tenants.utils import can_access


class BlockUnauthorizedUserMiddleware:
    """
    Raises 403 if the user making the request is not authorized
    explicitly to access the tenant instance!

    .. warning:

        This must be placed after
        ``django_tenants.middleware.main.TenantMainMiddleware`` and
        ``django.contrib.auth.middleware.AuthenticationMiddleware`` -
        usually goes at the end
    """

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):  # pylint: disable=no-self-use
        if not can_access(request.user, request.tenant):
            return HttpResponseForbidden(_("Unauthorized"))

        return self.get_response(request)


class BlockUnpaidTenantMiddleware:
    """
    Blocks unpaid tenants or adds warning messages if tenant is about to
    expire soon!

    .. warning:

        This must be placed after
        ``tcms_tenants.middleware.BlockUnauthorizedUserMiddleware`` -
        usually goes at the end.
    """

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if (request.tenant.paid_until is None) or (
            request.tenant.paid_until <= timezone.now()
        ):
            return HttpResponseForbidden(_("Unpaid"))

        if request.tenant.paid_until <= timezone.now() + timedelta(days=1):
            for msg in messages.get_messages(request):
                if msg.level_tag == "warning":
                    break
            else:
                # will be shown only if no other warnings are present
                messages.add_message(
                    request,
                    messages.WARNING,
                    _("Tenant expires soon"),
                    fail_silently=True,
                )

        return self.get_response(request)
