import sys
from importlib import reload

from django.contrib.auth.models import User
from django.core.signals import setting_changed
from django.test import TestCase, override_settings
from django.urls import resolve, reverse, NoReverseMatch, clear_url_caches

from martor.utils import markdownify
from martor.views import markdownfy_view, markdown_imgur_uploader, markdown_search_user


class SimpleTest(TestCase):
    def _on_settings_changed(self, sender, **kwargs):
        # Reload settings.py and urls.py when @override_settings is called
        clear_url_caches()
        reload(sys.modules["martor.settings"])
        reload(sys.modules["martor.urls"])
        reload(sys.modules["martor.tests.urls"])

    def setUp(self):
        self.user_password = "TestEgg@1234"
        self.user = User.objects.create_user(
            username="user1",
            email="user1@mail.com",
            password=self.user_password,
        )
        self.client.login(
            username=self.user.username,
            password=self.user_password,
        )

        setting_changed.connect(self._on_settings_changed)

    def tearDown(self):
        setting_changed.disconnect(self._on_settings_changed)

    def test_form(self):
        response = self.client.get("/test-form-view/")
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed("test_form_view.html")
        self.assertContains(response, "main-martor-description")
        self.assertContains(response, "main-martor-wiki")

    @override_settings(
        MARTOR_ENABLE_CONFIGS={
            "emoji": "true",  # enable/disable emoji icons.
            "imgur": "true",  # enable/disable imgur/custom uploader.
            "mention": "true",  # enable/disable mention
            "jquery": "true",  # include/revoke jquery (require for admin django) # noqa: E501
            "living": "false",  # enable/disable live updates in preview
            "spellcheck": "false",  # enable/disable spellcheck in form textareas # noqa: E501
            "hljs": "true",  # enable/disable hljs highlighting in preview
        },
        MARTOR_MARKDOWN_BASE_EMOJI_URL="https://github.githubassets.com/images/icons/emoji/",
        MARTOR_MARKDOWN_BASE_MENTION_URL="https://python.web.id/author/",
    )
    def test_markdownify(self):
        # Heading
        response = self.client.post(
            "/martor/markdownify/",
            {"content": "# Hello world!"},
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            response.content.decode("utf-8"), "<h1>Hello world!</h1>"
        )  # noqa: E501

        # Link
        response = self.client.post(
            "/martor/markdownify/",
            {"content": "[python](https://python.web.id)"},
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            response.content.decode("utf-8"),
            '<p><a href="https://python.web.id">python</a></p>',
        )  # noqa: E501

        # Image
        response = self.client.post(
            "/martor/markdownify/",
            {"content": "![image](https://imgur.com/test.png)"},
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            response.content.decode("utf-8"),
            '<p><img alt="image" src="https://imgur.com/test.png"></p>',
        )  # noqa: E501

        # Emoji
        response = self.client.post(
            "/martor/markdownify/",
            {"content": ":heart:"},
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            response.content.decode("utf-8"),
            '<p><img class="marked-emoji" src="https://github.githubassets.com/images/icons/emoji/heart.png"></p>',
        )  # noqa: E501

        # # Mention
        # response = self.client.post(
        #     "/martor/markdownify/",
        #     {"content": f"@[{self.user.username}]"},
        # )
        # self.assertEqual(response.status_code, 200)
        # self.assertEqual(
        #     response.content.decode("utf-8"),
        #     f'<p><a class="direct-mention-link" href="https://python.web.id/author/{self.user.username}/">{self.user.username}</a></p>',
        # )

    def test_markdownify_xss_handled(self):
        xss_payload_1 = "[aaaa](javascript:alert(1))"
        response_1 = markdownify(xss_payload_1)
        self.assertEqual(response_1, '<p><a href=":">aaaa</a></p>')

        xss_payload_2 = '![" onerror=alert(1) ](x)'
        response_2 = markdownify(xss_payload_2)
        self.assertEqual(
            response_2, '<p><img alt="&quot; onerror=alert(1) " src="x"></p>'
        )

        xss_payload_3 = '[xss](" onmouseover=alert(document.domain) l)'
        response_3 = markdownify(xss_payload_3)
        self.assertEqual(
            response_3,
            '<p><a href="&quot; onmouseover=alert(document.domain)">xss</a>)</p>',  # noqa: E501
        )

    def test_urls(self):
        with override_settings(
            MARTOR_MARKDOWNIFY_URL="test/url",
            MARTOR_UPLOAD_URL="",
            MARTOR_SEARCH_USERS_URL="",
        ):
            found = resolve(reverse("martor_markdownfy"))
            self.assertEqual(found.func, markdownfy_view)

            with self.assertRaises(NoReverseMatch):
                reverse("imgur_uploader")

            with self.assertRaises(NoReverseMatch):
                reverse("search_user_json")

        with override_settings(
            MARTOR_MARKDOWNIFY_URL="test/url",
            MARTOR_UPLOAD_URL="test/upload",
            MARTOR_SEARCH_USERS_URL="test/search",
        ):
            found = resolve(reverse("martor_markdownfy"))
            self.assertEqual(found.func, markdownfy_view)

            found = resolve(reverse("imgur_uploader"))
            self.assertEqual(found.func, markdown_imgur_uploader)

            found = resolve(reverse("search_user_json"))
            self.assertEqual(found.func, markdown_search_user)
