from django.test import TestCase, RequestFactory
from django.core.cache import cache
from django.http import HttpResponse, HttpResponseForbidden
from unittest.mock import patch
from regulations.middleware import SuspiciousActivityMiddleware, BlockScraperMiddleware


class MiddlewareTestCase(TestCase):
    def setUp(self):
        """Setup RequestFactory dan inisialisasi middleware sebelum setiap tes dijalankan."""
        self.factory = RequestFactory()

        # Middleware meneruskan request ke handler default yang mengembalikan response "OK"
        self.suspicious_middleware = SuspiciousActivityMiddleware(lambda req: HttpResponse("OK"))
        self.bot_middleware = BlockScraperMiddleware(lambda req: HttpResponse("OK"))

        cache.clear()  # Hapus cache sebelum setiap tes

    def test_suspicious_activity_middleware_blocks_excess_requests(self):
        """Middleware harus memblokir IP yang melakukan lebih dari 100 request dalam waktu singkat."""
        ip = "192.168.1.1"
        request = self.factory.get("/")
        request.META["REMOTE_ADDR"] = ip

        # Simulasikan lebih dari 100 request dari IP yang sama
        for _ in range(101):
            self.suspicious_middleware(request)

        # Permintaan ke-101 harus diblokir
        response = self.suspicious_middleware(request)
        self.assertEqual(response.status_code, 403)
        self.assertIn("Akses Diblokir", response.content.decode())

    def test_suspicious_activity_middleware_allows_normal_requests(self):
        """Middleware harus mengizinkan request normal tanpa pemblokiran."""
        ip = "192.168.1.2"
        request = self.factory.get("/")
        request.META["REMOTE_ADDR"] = ip

        response = self.suspicious_middleware(request)
        self.assertEqual(response.status_code, 200)  # Seharusnya diizinkan

    @patch("regulations.middleware.send_mail")

    def test_suspicious_activity_sends_alert_email(self, mock_send_mail):
        """Test middleware mengirim email peringatan jika aktivitas mencurigakan terdeteksi."""
        ip = "192.168.1.3"
        request = self.factory.get("/")
        request.META["REMOTE_ADDR"] = ip

        # Simulasi lebih dari 100 request
        for _ in range(101):
            self.suspicious_middleware(request)

        # Debugging
        print("Jumlah pemanggilan send_mail:", mock_send_mail.call_count)

        # Memastikan bahwa fungsi send_mail pernah dipanggil
        mock_send_mail.assert_called()

    def test_block_scraper_middleware_blocks_bots(self):
        """Middleware harus memblokir request dengan user-agent yang dikenali sebagai bot."""
        request = self.factory.get("/")
        request.META["HTTP_USER_AGENT"] = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

        response = self.bot_middleware(request)
        self.assertEqual(response.status_code, 403)
        self.assertIn("Access Denied", response.content.decode())

    def test_block_scraper_middleware_allows_normal_users(self):
        """Middleware harus mengizinkan request dari user-agent yang valid."""
        request = self.factory.get("/")
        request.META["HTTP_USER_AGENT"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"

        response = self.bot_middleware(request)
        self.assertEqual(response.status_code, 200)  # Seharusnya diizinkan
