from plone import api
from ploneintranet.news.testing import IntegrationTestCase
from ploneintranet.testing import temporary_registry_record
from Products.statusmessages.interfaces import IStatusMessage


class TestNewsTranslations(IntegrationTestCase):
    def test_code2name(self):
        news = self.portal.news["press-mentions"]["fusce-fames"]
        view = api.content.get_view("translations_view", news, self.request.clone())
        self.assertEqual(view.code2name("en"), "English")
        self.assertEqual(view.code2name("it"), "Italian")

    def test_get_translations(self):
        section = self.portal.news["press-mentions"]
        news1 = section["fusce-fames"]
        news2 = section["proin-netus"]
        news3 = section["class-velit-dis-velit-integer"]
        view1 = api.content.get_view("translations_view", news1, self.request.clone())
        view2 = api.content.get_view("translations_view", news2, self.request.clone())
        view3 = api.content.get_view("translations_view", news3, self.request.clone())

        # At the beginning we have no translation
        self.assertListEqual(view1.get_translations(), [])
        self.assertListEqual(view2.get_translations(), [])
        self.assertListEqual(view3.get_translations(), [])

        # We mock a translation
        api.relation.create(news1, news2, "translations")
        self.assertListEqual(view1.get_translations(), [news2])
        self.assertListEqual(view2.get_translations(), [news1])
        self.assertListEqual(view3.get_translations(), [])

        # The translations method can optionally take an argument
        self.assertListEqual(view3.get_translations(news1), [news2])

        # We mock another translation
        api.relation.create(news1, news3, "translations")
        self.assertListEqual(view1.get_translations(), [news2, news3])
        self.assertListEqual(view2.get_translations(), [news1, news3])
        self.assertListEqual(view3.get_translations(), [news1, news2])

        # Translations are sorted by language name
        news2.language = "it"
        self.assertListEqual(view1.get_translations(), [news3, news2])

    def test_language_menu_default_news(self):
        news = self.portal.news["press-mentions"]["fusce-fames"]
        view = api.content.get_view("translations_view", news, self.request.clone())
        self.assertEqual(view.get_obj_language_code(), "en")
        self.assertEqual(view.get_obj_language_name(), "English")
        self.assertEqual(view.default_language, "en")
        self.assertListEqual(view.get_translations(), [])

    def test_language_menu_news_it(self):
        news = self.portal.news["press-mentions"]["fusce-fames"]
        news.language = "it"
        view = api.content.get_view("translations_view", news, self.request.clone())
        self.assertEqual(view.get_obj_language_code(), "it")
        self.assertEqual(view.get_obj_language_name(), "Italian")
        self.assertEqual(view.default_language, "en")
        self.assertListEqual(view.get_translations(), [])

    def test_panel_create_language_forbidden_when_no_multilanguage(self):
        news = self.portal.news["press-mentions"]["fusce-fames"]

        # We cannot create a news while we do not have
        # multiple languages available in the site
        view = api.content.get_view("panel-create-language", news, self.request.clone())
        view.request.form["language"] = "it"

        self.assertSetEqual(view.allowed_languages, set())
        view.execute_on_post()

        self.assertDictEqual(
            view.request.response.headers,
            {"location": f"{news.absolute_url()}/edit.html"},
        )
        self.assertListEqual(
            [item.message for item in IStatusMessage(view.request).show()],
            ["The language you selected is not available"],
        )

    def test_panel_create_language_forbidden_when_wrong_language(self):
        news = self.portal.news["press-mentions"]["fusce-fames"]

        # We cannot create a news while we do not have
        # multiple languages available in the site
        view = api.content.get_view("panel-create-language", news, self.request.clone())
        view.request.form["language"] = "es"

        with temporary_registry_record("plone.available_languages", ["en", "it"]):
            self.assertSetEqual(view.allowed_languages, {"it"})
            view.execute_on_post()

        self.assertDictEqual(
            view.request.response.headers,
            {"location": f"{news.absolute_url()}/edit.html"},
        )
        self.assertListEqual(
            [item.message for item in IStatusMessage(view.request).show()],
            ["The language you selected is not available"],
        )

    def test_panel_create_language_forbidden_when_already_translated(self):
        news = self.portal.news["press-mentions"]["fusce-fames"]

        # We cannot create a news while we do not have
        # multiple languages available in the site
        view = api.content.get_view("panel-create-language", news, self.request.clone())
        view.request.form["language"] = "it"

        with temporary_registry_record("plone.available_languages", ["en", "it"]):
            self.assertSetEqual(view.allowed_languages, {"it"})

        translation = self.portal.news["press-mentions"]["proin-netus"]
        translation.language = "it"
        api.relation.create(news, translation, "translations")

        with temporary_registry_record("plone.available_languages", ["en", "it"]):
            self.assertSetEqual(view.allowed_languages, set())
            view.execute_on_post()

        self.assertDictEqual(
            view.request.response.headers,
            {"location": f"{news.absolute_url()}/edit.html"},
        )
        self.assertListEqual(
            [item.message for item in IStatusMessage(view.request).show()],
            ["The language you selected is not available"],
        )

    def test_panel_create_language_creates_translation(self):
        news = self.portal.news["press-mentions"]["fusce-fames"]

        # We cannot create a news while we do not have
        # multiple languages available in the site
        view = api.content.get_view("panel-create-language", news, self.request.clone())
        view.request.form["language"] = "it"

        with temporary_registry_record("plone.available_languages", ["en", "it"]):
            self.assertSetEqual(view.allowed_languages, {"it"})
            view.execute_on_post()

        # We expect a translation to be created with the same id + `-{language code}`
        translation = news.aq_parent[f"{news.getId()}-it"]

        # and we expect to be redirected there
        self.assertDictEqual(
            view.request.response.headers,
            {"location": f"{translation.absolute_url()}/edit.html"},
        )
        self.assertListEqual(
            [item.message for item in IStatusMessage(view.request).show()],
            [],
        )
        self.assertListEqual(view.translations_view.get_translations(), [translation])
        self.assertListEqual(
            view.translations_view.get_translations(translation), [news]
        )

    def test_panel_remove_language_does_not_remove_default(self):
        news = self.portal.news["press-mentions"]["fusce-fames"]
        translation = self.portal.news["press-mentions"]["proin-netus"]
        translation.language = "it"
        api.relation.create(news, translation, "translations")

        view = api.content.get_view("panel-remove-language", news, self.request.clone())
        view.execute_on_post()

        self.assertDictEqual(
            view.request.response.headers,
            {"location": f"{news.absolute_url()}/edit.html"},
        )

        self.assertListEqual(
            [item.message for item in IStatusMessage(view.request).show()],
            ["It seems that this content has translations"],
        )

    def test_panel_remove_language_removes_the_translation(self):
        news = self.portal.news["press-mentions"]["fusce-fames"]
        translation = self.portal.news["press-mentions"]["proin-netus"]
        translation.language = "it"
        api.relation.create(news, translation, "translations")

        view = api.content.get_view(
            "panel-remove-language", translation, self.request.clone()
        )
        view.execute_on_post()

        # Check we have a redirect to the original news with no errors
        self.assertDictEqual(
            view.request.response.headers,
            {"location": f"{news.absolute_url()}/edit.html"},
        )
        self.assertListEqual(
            [item.message for item in IStatusMessage(view.request).show()],
            [],
        )

        # Check the relations have been cleaned
        self.assertListEqual(news.translations, [])
