# -*- coding: utf-8 -*-
from __future__ import annotations

import typing

from django.db.models.fields import Field
from django.db.models.lookups import PatternLookup


class BaseLikeLookup(PatternLookup):
    """
    This class provides base for custom LIKE/ILIKE lookups for PostgreSQL.
    Unlike the builtin `contains` and `icontains`, these lookups do not do
    any DB-side processing of parameters. This opens up the ability to use
    index ops provided by `pg_trgm` to better index text columns for pattern
    searches.

    These lookups currently support only PostgreSQL 15+.
    """

    # This is the pattern operator used to generate SQL for the lookup
    # when the right hand side isn't a raw string. Subclasses must specify this
    # or the whole thing will blow up ;).
    PATTERN_OP: str | None = None

    # This is the rhs operator used to generate SQL for the lookup when the
    # right hand side is a raw string. Subclasses must specify this or the
    # whole thing will blow up ;).
    RHS_OP: str | None = None

    def get_rhs_op(self, connection: typing.Any, rhs: typing.Any) -> typing.Any:
        if hasattr(self.rhs, 'as_sql') or self.bilateral_transforms:
            pattern = typing.cast(str, self.PATTERN_OP).format(
                connection.pattern_esc,
            )

            return pattern.format(rhs)
        else:
            return typing.cast(str, self.RHS_OP)


@Field.register_lookup
class Like(BaseLikeLookup):
    PATTERN_OP = "LIKE '%%' || {} || '%%'"
    RHS_OP = 'LIKE %s'
    lookup_name = 'like'


@Field.register_lookup
class ILike(BaseLikeLookup):
    PATTERN_OP = "ILIKE '%%' || {} || '%%'"
    RHS_OP = 'ILIKE %s'
    lookup_name = 'ilike'
