# (c) cavaliba.com - tests / view texteditor raw format auto-detection

import json

from django.test import TestCase, override_settings
from django.urls import reverse

import app_home.cache as cache
from app_data.data import Instance
from tests import helper


class ViewTexteditorRawFormatTest(TestCase):
    def setUp(self):
        cache.clear()
        helper.add_admin_user(login="unittest")
        helper.add_schema(
            classname="rawtest",
            field_definition={
                "mystring": {"dataformat": "string", "displayname": "MyString"},
            },
        )

    def _post_raw(self, rawdata, submit, follow=False):
        data = {"rawdata": rawdata, "pipeline": "", "submit": submit}
        return self.client.post(reverse("app_data:texteditor"), data, follow=follow)

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_raw_yaml_import_auto_detected(self):
        """A block-style YAML list (doesn't start with "{"/"[") is parsed as YAML."""

        rawdata = "- classname: rawtest\n  keyname: row1\n  mystring: hello\n"
        response = self._post_raw(rawdata, "import")
        self.assertEqual(response.status_code, 302)
        instance = Instance.from_keyname(classname="rawtest", keyname="row1", expand=False)
        self.assertIsNotNone(instance)

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_raw_json_import_auto_detected(self):
        """Content starting with "[" is tried as JSON first."""

        rawdata = json.dumps([{"classname": "rawtest", "keyname": "row2", "mystring": "hello"}])
        response = self._post_raw(rawdata, "import")
        self.assertEqual(response.status_code, 302)
        instance = Instance.from_keyname(classname="rawtest", keyname="row2", expand=False)
        self.assertIsNotNone(instance)

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_raw_yaml_flow_style_list_falls_back_from_json(self):
        """Content starting with "[" that isn't valid JSON (unquoted keys) falls back
        to YAML, which parses flow style natively."""

        rawdata = "[{classname: rawtest, keyname: row3, mystring: hi}]"
        response = self._post_raw(rawdata, "import")
        self.assertEqual(response.status_code, 302)
        instance = Instance.from_keyname(classname="rawtest", keyname="row3", expand=False)
        self.assertIsNotNone(instance)

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_raw_syntax_error_reported(self):
        """Content that is neither valid JSON nor valid YAML reports an error."""

        response = self._post_raw("{not valid json", "verify")
        self.assertEqual(response.status_code, 200)
        rendered = [str(m) for m in response.context["messages"]]
        self.assertTrue(len(rendered) >= 1)

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_raw_content_not_a_list_is_rejected(self):
        response = self._post_raw("classname: rawtest\n", "verify")
        self.assertEqual(response.status_code, 200)
        rendered = [str(m) for m in response.context["messages"]]
        self.assertTrue(any("not a list" in m for m in rendered))

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_get_prefills_from_schema(self):
        """The "Edit as YAML" link from the Schema list still prefills the editor."""

        response = self.client.get(reverse("app_data:texteditor", args=["rawtest"]))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "rawtest")

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_get_prefills_from_instance(self):
        """The "Code" link from Instance detail still prefills the editor."""

        helper.add_instance(classname="rawtest", keyname="row4", fields={"mystring": "hi"})
        instance = Instance.from_keyname(classname="rawtest", keyname="row4", expand=False)

        response = self.client.get(reverse("app_data:texteditor", args=[instance.id]))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "row4")
