from django.db import connection
from django.test import TestCase

from ...threads.models import Thread
from ..pgutils import PgPartialIndex


class PgPartialIndexTests(TestCase):
    def test_multiple_fields(self):
        """multiple fields are supported"""
        with connection.schema_editor() as editor:
            sql = PgPartialIndex(
                fields=["has_events", "is_hidden"],
                name="test_partial",
                where={"has_events": True},
            ).create_sql(Thread, editor)

            self.assertIn('CREATE INDEX "test_partial" ON "misago_threads_thread"', sql)
            self.assertIn('ON "misago_threads_thread" ("has_events", "is_hidden")', sql)

    def test_where_clauses(self):
        """where clauses generate correctly"""
        with connection.schema_editor() as editor:
            sql = PgPartialIndex(
                fields=["has_events"], name="test_partial", where={"has_events": True}
            ).create_sql(Thread, editor)

            self.assertTrue(sql.endswith('WHERE "has_events" = true'))

            sql = PgPartialIndex(
                fields=["has_events"], name="test_partial", where={"has_events": False}
            ).create_sql(Thread, editor)
            self.assertTrue(sql.endswith('WHERE "has_events" = false'))

            sql = PgPartialIndex(
                fields=["has_events"], name="test_partial", where={"has_events": 42}
            ).create_sql(Thread, editor)
            self.assertTrue(sql.endswith('WHERE "has_events" = 42'))

            sql = PgPartialIndex(
                fields=["has_events"], name="test_partial", where={"has_events__lt": 42}
            ).create_sql(Thread, editor)
            self.assertTrue(sql.endswith('WHERE "has_events" < 42'))

            sql = PgPartialIndex(
                fields=["has_events"], name="test_partial", where={"has_events__gt": 42}
            ).create_sql(Thread, editor)
            self.assertTrue(sql.endswith('WHERE "has_events" > 42'))

            sql = PgPartialIndex(
                fields=["has_events"],
                name="test_partial",
                where={"has_events__lte": 42},
            ).create_sql(Thread, editor)
            self.assertTrue(sql.endswith('WHERE "has_events" <= 42'))

            sql = PgPartialIndex(
                fields=["has_events"],
                name="test_partial",
                where={"has_events__gte": 42},
            ).create_sql(Thread, editor)
            self.assertTrue(sql.endswith('WHERE "has_events" >= 42'))

    def test_multiple_where_clauses(self):
        """where clause with multiple conditions generates correctly"""
        with connection.schema_editor() as editor:
            sql = PgPartialIndex(
                fields=["has_events"],
                name="test_partial",
                where={"has_events__gte": 42, "is_hidden": True},
            ).create_sql(Thread, editor)
            self.assertTrue(
                sql.endswith('WHERE "has_events" >= 42 AND "is_hidden" = true')
            )

    def test_set_name_with_model(self):
        """valid index name is autogenerated"""
        index = PgPartialIndex(
            fields=["has_events", "is_hidden"], where={"has_events": True}
        )
        index.set_name_with_model(Thread)
        self.assertEqual(index.name, "misago_thre_has_eve_1b05b8_part")

        index = PgPartialIndex(
            fields=["has_events", "is_hidden", "is_closed"], where={"has_events": True}
        )
        index.set_name_with_model(Thread)
        self.assertEqual(index.name, "misago_thre_has_eve_eaab5e_part")

        index = PgPartialIndex(
            fields=["has_events", "is_hidden", "is_closed"],
            where={"has_events": True, "is_closed": False},
        )
        index.set_name_with_model(Thread)
        self.assertEqual(index.name, "misago_thre_has_eve_e738fe_part")

    def test_index_repr(self):
        """index creates descriptive representation string"""
        index = PgPartialIndex(fields=["has_events"], where={"has_events": True})
        self.assertEqual(
            repr(index),
            "<PgPartialIndex: fields='has_events', where='has_events=True'>",
        )

        index = PgPartialIndex(
            fields=["has_events", "is_hidden"], where={"has_events": True}
        )
        self.assertIn("fields='has_events, is_hidden',", repr(index))
        self.assertIn(", where='has_events=True'", repr(index))

        index = PgPartialIndex(
            fields=["has_events", "is_hidden", "is_closed"],
            where={"has_events": True, "is_closed": False, "replies__gte": 5},
        )
        self.assertIn("fields='has_events, is_hidden, is_closed',", repr(index))
        self.assertIn(
            ", where='has_events=True, is_closed=False, replies__gte=5'", repr(index)
        )