from django.conf import settings as s
from django.test import TestCase, override_settings
from django.urls import reverse

from epdb.logic import UserManager
from epdb.models import User

Package = s.GET_PACKAGE_MODEL()


@override_settings(MODEL_DIR=s.FIXTURE_DIRS[0] / "models", CELERY_TASK_ALWAYS_EAGER=True)
class ModelViewTest(TestCase):
    fixtures = ["test_fixtures_incl_model.jsonl.gz"]

    @classmethod
    def setUpClass(cls):
        super(ModelViewTest, cls).setUpClass()
        cls.user1 = UserManager.create_user(
            "user1",
            "user1@envipath.com",
            "SuperSafe",
            set_setting=True,
            add_to_group=True,
            is_active=True,
        )
        cls.user1_default_package = cls.user1.default_package
        cls.model_package = Package.objects.get(name="Fixtures")

    def setUp(self):
        self.client.force_login(self.user1)

    def test_predict(self):
        self.client.force_login(User.objects.get(username="admin"))
        response = self.client.get(
            reverse(
                "package model detail",
                kwargs={
                    "package_uuid": str(self.model_package.uuid),
                    "model_uuid": str(self.model_package.models.first().uuid),
                },
            ),
            {
                "classify": "ILikeCats!",
                "smiles": "CCN(CC)C(=O)C1=CC(=CC=C1)CO",
            },
        )

        expected = [
            {
                "products": [["CCN(CC)C(=O)C1=CC(C=O)=CC=C1"]],
                "probability": 0.75,
                "btrule": {
                    "url": "http://localhost:8000/package/1869d3f0-60bb-41fd-b6f8-afa75ffb09d3/simple-ambit-rule/2f2e0c39-e109-4836-959f-2bda2524f022",
                    "name": "bt0001-3568",
                },
            },
            {
                "products": [["O=C(O)C1=CC(CO)=CC=C1", "CCNCC"]],
                "probability": 0.25,
                "btrule": {
                    "url": "http://localhost:8000/package/1869d3f0-60bb-41fd-b6f8-afa75ffb09d3/simple-ambit-rule/0e6e9290-b658-4450-b291-3ec19fa19206",
                    "name": "bt0430-4011",
                },
            },
            {
                "products": [["CCNC(=O)C1=CC(CO)=CC=C1", "CC=O"]],
                "probability": 0.0,
                "btrule": {
                    "url": "http://localhost:8000/package/1869d3f0-60bb-41fd-b6f8-afa75ffb09d3/simple-ambit-rule/27a3a353-0b66-4228-bd16-e407949e90df",
                    "name": "bt0243-4301",
                },
            },
        ]

        actual = response.json()["pred"]
        self.assertEqual(actual, expected)

        response = self.client.get(
            reverse(
                "package model detail",
                kwargs={
                    "package_uuid": str(self.model_package.uuid),
                    "model_uuid": str(self.model_package.models.first().uuid),
                },
            ),
            {
                "classify": "ILikeCats!",
                "smiles": "",
            },
        )

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.json()["error"], "Received empty SMILES")

        response = self.client.get(
            reverse(
                "package model detail",
                kwargs={
                    "package_uuid": str(self.model_package.uuid),
                    "model_uuid": str(self.model_package.models.first().uuid),
                },
            ),
            {
                "classify": "ILikeCats!",
                "smiles": "  ",  # Input should be stripped
            },
        )

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.json()["error"], "Received empty SMILES")

        response = self.client.get(
            reverse(
                "package model detail",
                kwargs={
                    "package_uuid": str(self.model_package.uuid),
                    "model_uuid": str(self.model_package.models.first().uuid),
                },
            ),
            {
                "classify": "ILikeCats!",
                "smiles": "RandomInput",
            },
        )

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.json()["error"], '"RandomInput" is not a valid SMILES')
